「双重锁java」双重锁屏怎么关闭
今天给各位分享双重锁java的知识,其中也会对双重锁屏怎么关闭进行解释,如果能碰巧解决你现在面临的问题,别忘了关注本站,现在开始吧!
本文目录一览:
- 1、单例模式 java 双重锁用synchronized修饰之后还用volatile吗
- 2、在java中双重检查加锁为什么会失效
- 3、java单例双重检查锁为什么需要加volatile关键字
- 4、Java单例模式双重检验锁的第一次是否为空判断是什么目的
- 5、如何在Java中使用双重检查锁实现单例
单例模式 java 双重锁用synchronized修饰之后还用volatile吗
没有volatile修饰的uniqueInstance
[java] view plain copy
public class Singleton {
private static Singleton uniqueInstance;
private Singleton(){
}
public static Singleton getInstance(){
if(uniqueInstance == null){ //#1
synchronized(Singleton.class){ //#2
if(uniqueInstance == null){ //#3
uniqueInstance = new Singleton(); //#4
System.out.println(Thread.currentThread().getName() + ": uniqueInstance is initalized..."); //#5.1
} else {
System.out.println(Thread.currentThread().getName() + ": uniqueInstance is not null now..."); //#5.2
}
}
}
return uniqueInstance;
}
}
这样可能会导致结果 Singleton被实例化两次 ,这样就不符合单例的特点
原因分析:
1. thread2进入#1, 这时子线程的uniqueInstance都是为空的,thread2让出CPU资源给thread3
2. thread3进入#1, 这时子线程的uniqueInstance都是为空的, thread3让出CPO资源给thread2
3. thread2会依次执行#2,#3,#4, #5.1,最终在thread2里面实例化了uniqueInstance。thread2执行完毕让出CPO资源给thread3
4. thread3接着#1跑下去,跑到#3的时候,由于#1里面拿到的uniqueInstance还是空(并没有及时从thread2里面拿到最新的),所以thread3仍然会执行#4,#5.1
5. 最后在thread2和thread3都实例化了uniqueInstance
例子2:用volatile修饰的uniqueInstance
这里就不贴重复的代码了,因为只是加多一个volatile来修饰成员变量:uniqueInstance,
这样可以创建出一个单例实例。
原因分析:
volatile(java5):可以保证多线程下的可见性;
读volatile:每当子线程某一语句要用到volatile变量时,都会从主线程重新拷贝一份,这样就保证子线程的会跟主线程的一致。
写volatile: 每当子线程某一语句要写volatile变量时,都会在读完后同步到主线程去,这样就保证主线程的变量及时更新。
1. thread2进入#1, 这时子线程的uniqueInstance都是为空的(java内存模型会从主线程拷贝一份uniqueInstance=null到子线程thread2),thread2让出CPU资源给thread3
2. thread3进入#1, 这时子线程的uniqueInstance都是为空的(java内存模型会从主线程拷贝一份uniqueInstance=null到子线程thread2), thread3让出CPO资源给thread2
3. thread2会依次执行#2,#3,#4, #5.1,最终在thread2里面实例化了uniqueInstance(由于是volatile修饰的变量,会马上同步到主线程的变量去)。thread2执行完毕让出CPO资源给thread3
4. thread3接着#1跑下去,跑到#3的时候,会又一次从主线程拷贝一份uniqueInstance!=null回来,所以thread3就直接跑到了#5.2
5. 最后在thread3不再会重复实例化uniqueInstance了
在java中双重检查加锁为什么会失效
我个人认为既然是写的问题,可能对于程序来说同步代码块结束了,锁也就释放了,但是new这个过程是在计算机中真实存在的,因为是线程问题,如果在一个线程就不会出这种问题,总是建立好空间之后再运行下面,但是线程可能有极端情况这边还没建立好,那边已经开始读了。这样解释说得通。
java单例双重检查锁为什么需要加volatile关键字
已经修改,的确应该加上volatile关键字。不加的情况下,假设两个线程,线程A正在执行instance = new Instance()的操作,而线程B开始执行if(instance==null)的判断,当不存在volatile的时候,因为 new Instance()是一个非原子操作,可能发生无序写入,构造函数可能在整个对象构造完成前执行完毕,线程B可能会看到一个不完整的instance对象,因为java的某些实现会在内存中开辟一片存储对象的区域后直接返回内存的引用,所以线程B判断不为null,而这时候实际上,instance的构造函数还没有执行,从而线程b得到不完整的对象。在 Instance 的构造函数执行之前,会在内存中开辟一片存储对象的区域后直接返回内存的引用,赋值给变量 instance,instance也就可能成为非 null 的,即赋值语句在对象实例化之前调用,此时别的线程得到的是一个还会初始化的对象,这样会导致系统崩溃线程B可能会看到一个不完整的instance对象,因为java的某些实现,所以线程B判断不为null。从而得到不完整的对象。
Java单例模式双重检验锁的第一次是否为空判断是什么目的
第一次判断是否为空是位了保证是单例,只有初始是空的情况下才可以创建,synchronize里头的if判空是为了避免小概率事件发生,比如当对象还没创建时,有两个线程都通过了外部的判空,进入synchronize入口处,此时由于同步加锁,只有一个线程可以执行synchronize内部的代码(生成了单例对象),当它执行完释放了锁后,第二个线程就进入的synchronize内部的代码,如果此时不再判断一下的话,该对象就再次被创建了。
如何在Java中使用双重检查锁实现单例
public class SingleDemo {
private static SingleDemo s = null;
private SingleDemo(){}
public static SingleDemo getInstance(){
/*如果第一个线程获取到了单例的实例对象,
* 后面的线程再获取实例的时候不需要进入同步代码块中了*/
if(s == null){
//同步代码块用的锁是单例的字节码文件对象,且只能用这个锁
synchronized(SingleDemo.class){
if(s == null){
s = new SingleDemo();
}
}
}
return s;
}
}
用这种方式解决了懒汉式的线程安全问题,也提高了效率,但是在实际开发中还是用饿汉式的比较多,毕竟这个代码比较多,比较繁琐。望采纳,谢谢。
关于双重锁java和双重锁屏怎么关闭的介绍到此就结束了,不知道你从中找到你需要的信息了吗 ?如果你还想了解更多这方面的信息,记得收藏关注本站。