非常经典的一段死锁的代码
1,概念:
在多线程环境中,我们经常会遇到多个线程访问同一个共享资源的情况,这个时候必须考虑如何维护数据一致性,常见的方式是加锁处理。只有拿到锁的线程才可以访问共享资源,通过锁就可以让线程对共享资源的访问都是顺序的,避免出现一些数据不一致的问题。
在使用锁的过程中同样也有风险,最为常见的就是死锁现象。死锁就相当于绳子打死结一样,解不开了。在程序中出现这样的情况往往是由于多个线程同时锁住多个资源不释放导致的。
2,上代码
/** * @Auther: wangbao02 * @Date: 2018/7/9 09:57 * @Description: */ public class Deadlock { public static String str1 = "str1"; public static String str2 = "str2"; public static void main(String[] args){ Thread a = new Thread(() -> { try{ while(true){ synchronized(Deadlock.str1){ System.out.println(Thread.currentThread().getName()+"锁住 str1"); Thread.sleep(1000); synchronized(Deadlock.str2){ System.out.println(Thread.currentThread().getName()+"锁住 str2"); } } } }catch(Exception e){ e.printStackTrace(); } }); Thread b = new Thread(() -> { try{ while(true){ synchronized(Deadlock.str2){ System.out.println(Thread.currentThread().getName()+"锁住 str2"); Thread.sleep(1000); synchronized(Deadlock.str1){ System.out.println(Thread.currentThread().getName()+"锁住 str1"); } } } }catch(Exception e){ e.printStackTrace(); } }); a.start(); b.start(); } }
上面的代码就是一个完整的死锁程序,程序中有两个线程,线程1锁住了str1,获得锁之后休眠1秒钟,这个时候线程2锁住了str2,也进行休眠操作。
线程1休眠完了之后去锁str2,但是str2已经被线程2给锁住了,这边只能等待,同样的道理,线程2休眠完之后也要去锁str1,同样也会等待,这样死锁就产生了。
如果我们将下面这2行代码的值改成一样,死锁还会存在吗?
public static String str1 = "str1"; public static String str2 = "str1";
答案是不会,为什么?
网上看到别人的回答:在声明一个对象作为锁的时候要注意字符串类型锁对象,因为字符串有一个常量池,如果不同的线程持有的锁是具有相同字符的字符串锁时,两个锁实际上同一个锁。