java设计模式之单列模式(懒汉,恶汉,double-check- lock)
来源:互联网 发布:淘宝产品视频 编辑:程序博客网 时间:2024/05/16 07:51
一:恶汉模式,类加载的时候就已经把对象初始化好了。(为了防止在其他类中使用new 操作符创建对象,要使用一个private 标记的 构造方法)
package single;public class Singleton1 {public static final Singleton1 singleton=new Singleton1();private Singleton1() {}public static Singleton1 getInstance(){return singleton;}}
二:懒汉模式(懒加载)
package single;public class Singleton2 {public static Singleton2 singleton2 = null;private Singleton2() {// TODO Auto-generated constructor stub}public static Singleton2 getInstance() {if (singleton2 == null) {// 1singleton2 = new Singleton2();//2}return singleton2;}}
这种懒汉模式会造成线程安全问题,比如假如有两个线程A,B,都执行到上面的第二步,那么就生成了两个对象,后执行第二步生成的对象替换掉了
先执行第二步生成的那个对象。怎么办呢,加锁啊。。
三:加上同步锁
package single;public class Singleton3 {public static Singleton3 singleton3 = null;private Singleton3() {// TODO Auto-generated constructor stub}public synchronized static Singleton3 getInstance() {if (singleton3 == null) {// 1singleton3 = new Singleton3();// 2}return singleton3;}}
上面到不会造成线程安全问题了。但是效率低啊,假设有10个线程,第一个线程执行方法的时候,后面的都得排队。。怎么办?换个方式加锁
四:同步锁2
package single;public class Singleton4 {public static Singleton4 singleton4=null;private Singleton4() {// TODO Auto-generated constructor stub}public static Singleton4 getInstance(){if(singleton4==null){//1synchronized(Singleton4.class){singleton4 =new Singleton4();//2}}return singleton4;}}
这个和三的列子差不多,虽然好点,但是仍然会造成线程并发问题,假如有10个线程执行了第一步,进行了null check,然后就会创建10个对象,怎么办呢,double-check- lock .
五:同步锁3
package single;public class Singleton5 {public static Singleton5 singleton5=null;private Singleton5() {// TODO Auto-generated constructor stub}public static Singleton5 getInstance(){if(singleton5==null){//1synchronized(Singleton5.class){if(singleton5==null){//2singleton5 =new Singleton5();//3}}}return singleton5;}}
怎么样呢?似乎是完美无缺啊。但是,仍然不行,因为第三步 singleton5=new Singleton5()并不是原子操作,他事实上分三步 (1),分配 memory,(2)把对象的引用 指派给memory (3) 初始化memory,假如有一个线程,执行完了同步块,但是却卡在了(3)步,那么其他线程拿到的就是一个没有被初始化完成的对象。囧。。。。。不过别担心,我们仍然有办法。
五:变量singleton5前加volatile 关键字(volatile关键字保证了可见性,但不保证原子性,可见性的意思就是,一个线程对一个资源的修改,另一个线程会得到通知。可以参考这篇blog)不过据说有些jvm并没有实现volatile规范。。。。。)
六:内部类方式。
如果想保证线程安全,不想要lazy加载的话,第一种最合适,但如果想要线程安全,又先要lazy加载的话,我们还可以使用内部类的方式。
package single;public class Singleton6 {private static class InnerClass {public static final Singleton6 singleton6 = new Singleton6();}public static Singleton6 getInstance() {return InnerClass.singleton6;}}
内部类在第一次被调用的时候才被初始化
七:最高端大气上档次的是enum枚举类的方式
package single;public enum Singleton7 {singleton7;}
每一个枚举类的常量都是这个枚举类的一个实列。。。。。
1 0
- java设计模式之单列模式(懒汉,恶汉,double-check- lock)
- Java设计模式之单例模式(恶汉式和懒汉式)
- 【JAVA】设计模式之懒汉式与恶汉式的单例模式实现的方法与详解
- java设计模式之单列
- 单例模式-恶汉-懒汉
- 单列模式,懒汉 ,饿汉
- 【趣解】单例模式之懒汉式、恶汉式
- JAVA单例设计模式简单实现(懒汉与恶汉),多例设计模式的简单实现
- 设计模式之单列
- java单列设计模式
- Java单列设计模式
- 单例模式中的Double check lock
- 设计模式之单列模式
- 设计模式之单列模式
- 设计模式之单列模式
- 设计模式之单列模式
- 单例模式(懒汉、恶汉式)
- java设计模式--单列模式
- 抽奖工具
- 手势密码锁
- 创建返回游标的函数与在java中调用取值
- ZWAVE Door Lock Operation
- 对张量奇学长所提问题的解答
- java设计模式之单列模式(懒汉,恶汉,double-check- lock)
- C實踐項目3.3—發工資
- 手机不打印日志和Logger日志库的使用
- iPad尺寸详解
- Java用SAX解析XML
- 使用Python进行数学图表绘制
- Visual Studio Code开发nodejs
- 主成分分析(PCA)
- Android知识架构 · 电话面试 · 性能优化和兼容性