998元网站建设优化,资源搜索引擎搜索神器网,佛山网站建设与推广,怎样在亚马逊网上开店1. 饿汉模式
饿坏了#xff0c;上来就先实例化一个对象#xff0c;好处是代码简单#xff0c;坏处是这个对象后面如果一直用不到#xff0c;就是个浪费。 public class A{ private static A a new A(); private A(){} public static A getInstance(){ return a; } } 2. 懒…1. 饿汉模式
饿坏了上来就先实例化一个对象好处是代码简单坏处是这个对象后面如果一直用不到就是个浪费。 public class A{ private static A a new A(); private A(){} public static A getInstance(){ return a; } } 2. 懒汉模式
懒洋洋的用到的时候才抱佛脚。最简单的懒汉模式如下存在线程安全问题。 public static class A{ private static A anull; private A(){} public static A getInstance(){ if(anull){ anew A(); } return a; } } 终极解决办法是使用DCLdouble check lock加volatile如下所示 public static class A{ private static volatile A anull; private A(){} public static A getInstance(){ if(anull){ synchronized (A.class){ if(anull){ anew A(); } } } return a; } } DCL其实就是一锁二判三更新在一锁之前加一个判断提高并发时的效率不需要每次一上来都先锁住消耗性能。加volatile的目的是防止第8行发生指令重排。
第8行在底层会有3个操作
分配一块内存初始化这块内存一般是调用类的构造函数将这块内存赋给变量如上代码中是变量a
如果在变量a不加volatile上面的步骤可能发生指令重排变成1、3、2导致a先等于一块没有初始化2还未执行或初始化一半2执行了一半的内存这时候如果代码其他部分不需要获取A.class的锁的部分访问了a变量就会读到预料外的值。 这有点类似于数据库里的“脏读”在事务处理中的数据被该事务外读到。