Java单例模式的几种写法
分类:Java, Java语言, Uncategorized
阅读 (1,040)
Add comments
9月 052019
一、饿汉模式
饿汉模式在声明静态内部对象时就创建该对象,就是不管在程序中是否用到这个静态对象都会创建它,对于不一定会使用该对象的程序是一种资源的浪费,代码如下:
1 2 3 4 5 6 7 8 9 |
public class SingletonTest { private static SingletonTest _singleton = new SingletonTest(); private SingletonTest() { } public static SingletonTest instance(){ return _singleton; } } |
因为饿汉模式在声明的时候就创建了,所以不会有线程安全问题
对于构造函数需要传入参数的单例也没办法这样创建
二、懒汉模式
懒汉模式,即在使用的时候才去创建它,相对于饿汉他有点懒,但其实他不懒
代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 |
public class SingletonTest { private static SingletonTest _singleton ; private SingletonTest() { } public static SingletonTest instance(){ if(_singleton == null) { _singleton = new SingletonTest(); } return _singleton; } } |
假如在多个线程中都会用到这个单例对象,那么就有可能造成实例出多个对象的问题了,就是这种方式是线程不安全的
三、锁方法的懒汉模式(不推荐使用)
我们在instance()方法前加上synchronized修饰,这样多个线程就不可能同时进入instance方法了,也不会造成new多个实例的问题了
代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 |
public class SingletonTest { private static SingletonTest _singleton = null; private SingletonTest() { } public synchronized static SingletonTest instance(){ if(_singleton == null) { _singleton = new SingletonTest(); } return _singleton; } } |
四、局部锁(不可使用)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
public class SingletonTest { private static SingletonTest _singleton = null; private SingletonTest() { } public static SingletonTest instance(){ if(_singleton == null) { synchronized (SingletonTest.class) { _singleton = new SingletonTest(); } } return _singleton; } } |
这种方式看似加了一个锁,但是多个线程可能同时进入到if的判断语句中,同样不能保证_singleton的唯一性
五、双重检查锁+volatile修饰(推荐使用)
代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
public class SingletonTest { private volatile static SingletonTest _singleton = null; private SingletonTest() { } public static SingletonTest instance(){ if(_singleton == null) { synchronized (SingletonTest.class) { if(_singleton == null) { _singleton = new SingletonTest(); } } } return _singleton; } } |