(三)—-死锁(面试常见)

最后更新于: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(); } } ~~~
';