目录
1.单例模式
单例模式是一种设计模式。单例模式能保证某个类在程序中只存在唯⼀⼀份实例, ⽽不会创建出多个实例.
举例:
package 多线程;
import javax.management.MBeanAttributeInfo;
//就期望这个线程只有一个实例
class Singleton{
private static Singleton instance = new Singleton();//类一被启动就会初始化这个静态成员,实例创建的非常早
public static Singleton getInstance(){
return instance;
}
private Singleton(){}
}
public class ThreadDemo21 {
public static void main(String[] args) {
Singleton s = Singleton.getInstance();
Singleton s2 = Singleton.getInstance();
System.out.println(s == s2);
}
}
私有的构造函数确保其他类无法通过直接实例化来创建 Singleton 的对象。而静态的 instance 成员变量在类加载时就被初始化,因此在整个程序中只会有一个 Singleton 的实例。我们用getInstance方法获取到实例,并赋值给s和s2,最后我们通过比较发现是同一个实例所以会输出true。
1.1单例模式的实现
单例模式具体的实现⽅式有很多. 最常⻅的是 "饿汉" 和 "懒汉" 两种.
饿汉模式:
我们上面的例子就是一个饿汉模式的例子,他的特点就是成员变量在被类加载的时候就被初始化了。优点是实现简单,线程安全,缺点是无法延迟实例化,可能会造成资源浪费。
package 多线程;
import javax.management.MBeanAttributeInfo;
//就期望这个线程只有一个实例
class Singleton{
private static Singleton instance = new Singleton();//类一被启动就会初始化这个静态成员,实例创建的非常早
public static Singleton getInstance(){
return instance;
}
private Singleton(){}
}
public class ThreadDemo21 {
public static void main(String[] args) {
Singleton s = Singleton.getInstance();
Singleton s2 = Singleton.getInstance();
System.out.println(s == s2);
}
}
懒汉模式:
懒汉模式是一种常见的单例模式实现方式,它的特点是在第一次使用时才会创建单例实例。这样可以避免在程序启动时就创建对象,从而节省资源。
举例:
class Singleton {
private static Singleton instance = null;
private Singleton() {}
public static Singleton getInstance() {
if (instance == null) {
instance = new Singleton();
}
return instance;
}
}
当我们第一次调用getInstance方法的时候就是第一次使用单例实例。但是这个代码如果在多线程是不安全的,因为当多个线程同时调用 getInstance() 方法时,都发现 instance 为 null,则会同时创建多个实例,导致不符合单例模式的要求。所以我们可以加上synchronizied关键字。
代码如下:
package 多线程;
//懒汉的方式实现单例模式
class SingletonLazy{
//引用指向唯一实例,这个引用先初始化位null,而不是立即创建实例
private volatile static SingletonLazy instance =null;
private static Object locker = new Object();
public static SingletonLazy getInstance(){//如果首次调用getInstance,那么instance引用为null就会进入if条件,把实例创建出来
if(instance == null){
synchronized (locker){
if (instance == null){
instance = new SingletonLazy();
}
}
}
return instance;
}
}
public class ThreadDemo22 {
public static void main(String[] args) {
SingletonLazy s1 = SingletonLazy.getInstance();
SingletonLazy s2 = SingletonLazy.getInstance();
System.out.println(s1 == s2);
}
}
这样我们的代码就不会出现安全问题。最后也会输出true。
希望大家多多支持!