网站招聘顾问做啥的,wordpress aliay,wordpress ajax post,wordpress 百度搜索单例模式#xff1a;双重效验锁的懒汉实现方式 单例模式饿汉模式实现懒汉模式实现改进1 (创建多个实例)改进2 (性能比较低)改进3 (volatile禁止指令重排序) 单例模式 单例模式顾名思义就是指实例化一个对象#xff0c;通过把构造方法私有化来禁止创建实例。 饿汉模式实现 饿汉… 单例模式双重效验锁的懒汉实现方式 单例模式饿汉模式实现懒汉模式实现改进1 (创建多个实例)改进2 (性能比较低)改进3 (volatile禁止指令重排序) 单例模式 单例模式顾名思义就是指实例化一个对象通过把构造方法私有化来禁止创建实例。 饿汉模式实现 饿汉模式的特点是在类加载的时候就创建并初始化一个实例实例在整个程序运行期间都是唯一的 public class Singleton {private static Singleton instance new Singleton();private Singleton() {}public static Singleton getInstance() {return instance;}
}这里的getInstance()必须是静态方法因为静态方法可以通过类名.方法名的方式调用而非静态方法则要创建实例这与我们单例模式的规则不相符。
懒汉模式实现 懒汉模式的特点是需要的时候再创建实例实例在整个程序运行期间都是唯一的。 public class Singleton {private static Singleton instance null;private Singleton() {}public static Singleton getInstance() {if (null instance) {instance new Singleton();}return instance;}
}上面代码在单线程模式下是没问题的但是在多线程模式下就会存在线程安全问题。 如果在首次创建实例多个线程同时调用getInstance()方法,就有可能创建多个实例。
改进1 (创建多个实例)
我们可以进行对 getInstance() 方法进行加锁
public class Singleton {private static Singleton instance null;private Singleton() {}public static synchronized Singleton getInstance() {if (null instance) {instance new Singleton();}return instance;}
}这样虽然解决刚刚线程安全的问题,但每次调用getInstance()方法都要加锁,增加不少的开销。 我们发现上面线程安全问题只存在于首次创建实例的情况因此我们只需要对instance为空的时候单独处理即可。
改进2 (性能比较低)
当instance为空的时候加锁再判断一次是否为空即可
public class Singleton {private static Singleton instance null;private Singleton() {}public static Singleton getInstance() {if (null instance) {synchronized (Singleton.class) {if (null instance) {instance new Singleton();}}}return instance;}
}粗略的看上去好像没什么问题实际上这里还有一个指令重排序的问题
通过查阅资料知道instance new Singleton();这个代码在执行的时候实际是执行分3步骤执行
memory allocate(); //1.分配对象的内存空间
ctorInstance(memory); //2. 初始化对象
instancememory; //3. 设置instance指向刚分配的内存地址JVM在执行的时候可能就会优化成 1-3-2的顺序执行 可能导致在多线程环境下,还没执行2就已经被其他线程返回了一个刚分配的地址 同样存在线程安全问题需要使用volatile关键字来禁止指令重排序。
改进3 (volatile禁止指令重排序)
public class Singleton {//volatile 防止指令重排 和可见性private static volatile Singleton instance null;private Singleton() {}public static Singleton getInstance() {//先判断对象是否已经实例化过没有实例化才进入加锁代码if (null instance) {//类对象加锁synchronized (Singleton.class) {//避免 singleTon null时第一个线程实例化后进入阻塞状态的线程被唤醒后仍会进行实例化。if (null instance) {instance new Singleton();}}}return instance;}
}以上就是线程安全的懒汉模式。