死锁

作者: zhengqiuliu | 来源:发表于2019-07-15 13:38 被阅读0次

    上一篇列举了死锁的例子,就是两个线程互相竞争对方的资源,而又不释放自己的资源,导致互相死等。如下图所示:

    死锁发生的条件:

    1,互斥,共享资源X和Y只能被一个线程占用。

    2,占用且等待,线程T1已经取得共享资源X,在等待共享资源Y的时候,不释放共享资源X。

    3,不可抢占,其他线程不能强行抢占线程T1占有的资源。

    4,循环等待,线程T1等待线程T2占有的资源,线程T2等待线程T1占有的资源,就是循环等待。

    只要我们破坏其中一个,就可以成功避免死锁的发生。

    1,互斥这个条件我们没有办法破坏,因为我们用锁就是为了互斥。

    2,破坏占用且等待条件。

    从理论上讲,破坏这个条件,可以一次性申请所有资源。对于转账操作来说,需要的资源有两个,一个是转出账户,另一个是转入账户。可以增加一个账本管理员,然后只允许账本管理员从文件架上拿账本,只有申请的资源都在时候,账本管理员才进行操作。

    这里有一个细节需要注意,管理员如果发生申请的资源没有同时在的时候,可以有两种操作:一是直接使用while循环进行等待,二是通过wait(),notifyall()等待-通知进行操作。

    3,破坏不可抢占条件。

    不可抢占的核心是能够主动释放它占有的资源,这一点synchronized是做不到的。原因是synchronized申请资源的时候,如果申请不到,线程就直接进入阻塞状态了,而线程进入阻塞状态,啥都干不了,也释放不了线程占用的资源。java.util.concurrent这个包下面提供了Lock是可以轻松解决这个问题的。

    4,破坏循环等待条件。

    破坏这个条件可以对资源进行排序,然后按照顺序申请资源。就不是出现两个线程都申请到了对方资源而互相等待这种情况,因为资源申请的顺序已经确定了。如果线程1申请资源1,那么线程2就只能等待了。

    相关文章

      网友评论

          本文标题:死锁

          本文链接:https://www.haomeiwen.com/subject/laqnkctx.html