- 饿汉式 :线程安全(普通)
Class Singleton{
private Singleton(){} //1.私有构造函数
private static Singleton instance = new Singleton (); //2.创建本类对象
public static Singleton getInstance(){ //3.对外提供公共的访问方式
return instance;
}
}
- 懒汉式:线程不安全(普通)
public class Singleton {
private Singleton(){}; //1.私有构造函数
private static Singleton instance; //2.声明一个本类的引用
public static Singleton getInstance(){ //3.对外提供公共的访问方式
if(instance == null){
instance = new Singleton();
}
return instance;
}
}
- 饿汉式:线程安全(使用static final修饰,不能被更改)
1 class Singleton {
2 private Singleton(){};
3 public static final Singleton s = new Singleton(); //被final修饰的变量不能被更改
4 }
- 静态内部类:线程安全 (使用内部类)
1 public class Singleton {
2 private Singleton() {
3 }
4
5 public static Singleton getInstance() {
6 return SingletonHolder.mInstance;
7 }
8
9 private static class SingletonHolder {
10 private static final Singleton mInstance = new Singleton();
11 }
12 }
- 懒汉模式:线程安全(volatile和sync修饰)
1 public class Singleton {
2 public volatile static Singleton singleton = null;
3 private Singleton(){ //构造方法私有化,防止外部调用生成实例化,比如反射
4 if(singleton!=null){
5 throw new RuntimeException("此类对象为单例模式,已经被实例化");
6 }
7 }
8
9 /**
10 * 1.为什么会有线程不安全的问题?
11 * 如果不加同步块,那么线程A抢到走到此if (singleton == null) 停了,线程B此时抢到了就new了一个对象,当线程B
12 * 走完了,线程A就接着此if (singleton == null)继续执行,此时就又new了一个对象,这样就导致new了两个对象
13 * 2.为什么加了同步块,外层还要加此句判断?
14 * 因为如果当是单线程的时候也会同步了,就影响了性能
15 */
16 public static Singleton getSingleton(){
17 if(singleton==null) {
18 synchronized (Singleton.class) { //通过反射:类名.class 得到Class类对象
19 if (singleton == null) {
20 singleton = new Singleton();
21 }
22 }
23 }
24 return singleton;
25 }
26 }