单例模式
单例模式又叫做单态模式,保证一个类仅有一个实例。
/*饿汉式,浪费资源
* 保证次类的对象,具有唯一性
单例
1:私有修饰构造方法
2创建本类对象
3公共方法返回本类对象
*/
public class Single {
private Single() {}
private static Single s=new Single();
public static Single getInstnstace() {
return s;
}
}
....................................
public class SingleDemo {
public static void main(String[] args) {
//使用Single类的对象不能new
//通过静态方法获取
Single s=Single.getInstnstace();
System.out.println(s);
Single s1=Single.getInstnstace();
System.out.println(s1==s);
}
}
//懒汉式
public class Single {
private Single() {}
private static Single s=null;
public static Single getInstnstace() {
//只创建一次
if (s==null) {
s=new Single();
}
return s;
}
public static void method() {
System.out.println("method方法");
}
}
.........................................
//懒汉式∶出现线程安全问题
//if(s==nu11)
//多个线程(CPU挂起)
//同步方法以后,不行 锁太重
public class Single {
private single(){}
private static Single s = nu1l;
public static synchronized single getInstnce(){
if(s == null) {
s = new Single();}
return s;
}
}
.......................................
//变为同步代码块
public staticsingle getInstnce() {
synchronized ( Single.class) {
if(s ==nu11){
s=new single( );
}
}
return s;
}
.............................................
//如果一个线程,运行后,变量s不是空,对象地址
//当下一个线程,再运行没有必要在拿锁,再判断,直接return
public staticsingle getInstnce() {
if(s ==nu11){
synchronized ( Single.class) {
if(s ==nu11){
snew single( );
}
}
}
return s;
}
面试题(半初始化)
单例设计模式DCL,成员变量,是否需要添加关键字volatile 加,必须加
volatile(修饰符)写在成员变量,防止指令重排序
创建对象指令:
1.堆内存开辟空间(地址)
2.初始化自己的成员变量 private int a=1
2.1 先赋值默认值0
2.2定义值
3.调用构造方法
4.地址传递给引用变量
以上指令,按照顺序进行,如果CPU出现了指令上乱序,出现对象没有创建完成,先将内存的地址赋值到引用变量,如果另一个线程执行,带走变量,没有创建完成的对象!!
面试题(volatile)
保证内存的可见性:内存中的数据,只要有1个线程进行了更新,其他线程都会读取到最新的数据
面试题(JDK锁升级)
一个对象,做为同步锁来使用,锁会有四个状态
- 无锁:被创建, new出来的时候,无锁状态
- 偏向锁:进入同步的时候,升级为偏向锁,偏向摸一个线程
- 轻量锁:CAS(CompareAndSwap)自旋锁
。线程读取数据,修改后,和原数据对比,无变化就保存
。线程读取数据,修改后,和原数据对比,有变化就从新读取数据
。CAS锁,出现ABA的问题,解决思想version,版本号 - 重锁
。CAS锁满足一个条件,升级为重锁
。一个线程自选的次数超过10次
。正在自旋的线程个数,超过CPU线程个数的一半
。两个条件满足一个,升级为重锁