线程同步导致的问题死锁哲学家进餐问题

请关注我的微信公众号

个人微信公众号

技术交流群 (仅作技术交流):642646237

​请关注我的头条号:

线程同步导致的问题

让多线程代码安全运行的方法只能是让所有的方法都同步。

  • 效率低下。
    如果每个方法都同步,大多数线程会频繁阻塞,使程序失去了并发的意义。-
  • 当使用多把锁时(Java中每一个对象都有自己的内置锁),线程之间可能发生死锁。

哲学家进餐问题——死锁——示意图

线程同步导致的问题死锁哲学家进餐问题_第1张图片

哲学家进餐问题——死锁——代码

代码很简单,Philosopher类只有三个属性,左右筷子和random:

线程同步导致的问题死锁哲学家进餐问题_第2张图片

下面是具体的逻辑代码:
线程同步导致的问题死锁哲学家进餐问题_第3张图片

测试该代码:


线程同步导致的问题死锁哲学家进餐问题_第4张图片

哲学家进餐问题——死锁——代码运行多久会死锁

测试过五个哲学家实例,最长时间可以运行一周,直到某个时刻突然都停了下来。

哲学家进餐问题——死锁——原因

如果所有哲学家同时决定进餐,都拿起左手边的筷子,那么就无法进行下去——所有人都持有一只筷子并等待右手边的人放下筷子。这时死锁就出现了。

哲学家进餐问题——死锁条件

一个线程需要多把锁时,就需要考虑死锁的可能性。

哲学家进餐问题——如何避免死锁

总是按照一个全局的固定的顺序获取多把锁。


线程同步导致的问题死锁哲学家进餐问题_第5张图片

不是按左右手的顺序拿筷子,而是按照筷子编号获取锁(不关心编号的具体规则,只要保证编号是全局唯一且有序的)。

如果获取锁的代码写得比较集中,就有利于维护这个全局顺序。而对于规模较大的程序,使用锁的地方比较零散,各处都遵守这个顺序就变得不太实际。

用对象的散列值作为锁的全局顺序

线程同步导致的问题死锁哲学家进餐问题_第6张图片

适用于所有Java对象,不用为锁对象专门定义并维护一个顺序。
但对象的散列值并不能保证唯一性(对象的散列值可能重复)。如果不是迫不得已,不要使用这个技巧。

你可能感兴趣的:(线程同步导致的问题死锁哲学家进餐问题)