(三)—-死锁(面试常见)
最后更新于:2022-04-01 10:16:25
### 延迟加载的单例多线程设计模式(懒汉式)
单例模式
是让调用者只产生一个唯一的对象。
分为饿汉式和懒汉式
**饿汉式:**
~~~
class EHan{
private static final EHan e = new EHan();
public eHan(){}
public static EHan getInstance(){
return e;
}
}
~~~
**懒汉式:**
~~~
class LanHan{
private static LanHan e = new LanHan();
public LanHan(){}
public static LanHan getInstance(){
if(e == null){
e = new LanHan();
return e;
}
return e;
}
}
~~~
这里懒汉式的写法存在多线程的安全性问题,通过同步锁来解决这个问题。
~~~
class LanHan{
private static LanHan e = new LanHan();
public LanHan(){}
public static LanHan getInstance(){
if(e == null){ //这种写法,减少判断同步锁的次数,并同样达到同步代码的作用。
synchronized(LanHan.class){
if(e == null){
e = new LanHan();
return e;
}
}
}
return e;
}
}
~~~
### 死锁的产生原因
1)产生原因:同步代码中嵌套同步.
2)当flag为true时,同步代码块(定义为代码块1)拿到objA的锁,执行代码块中的内容。接着要拿到objB的锁,
此时flag为false,值行flag为false的代码(定义为2),同步代码块拿到objB的锁,需要拿到objA的锁,还没有执行完代码块中的代码,并没有释放objB的锁。
因此代码块1拿不到objB的锁,代码快没有执行完,不释放objA的锁。
因此产生了死锁。
~~~
class SyncRunnable implements Runnable{
public boolean flag = false;
public static Object objA = new Object();
public static Object objB = new Object();
public void run(){
if(flag){
while(true){ //定义为:代码块1
synchronized(objA){ //objA锁
System.out.println("if objA----");
synchronized(objB){ //objB锁
System.out.println("if objB----");
}
}
}
}else{
while(true){ // 定义为:代码块 2
synchronized(objB){ //objB锁
System.out.println("else objB----");
synchronized(objA){ //objA锁
System.out.println("else objA----");
}
}
}
}
}
}
public class SingleInstance{
public static void main(String args[]){
SyncRunnable sr1 = new SyncRunnable();
sr1.flag = true;
SyncRunnable sr2 = new SyncRunnable();
sr2.flag = false;
Thread t1 = new Thread(sr1);
Thread t2 = new Thread(sr2);
t1.start();
t2.start();
}
}
~~~