死锁

在实际编程中,死锁虽然不常见,但是如果遇到死锁便是致命的。接下来了解一下《操作系统》对于死锁产生条件的描述。

死锁产生的条件:

  1. 互斥条件:所谓互斥就是进程在某一时间内独占资源。

  2. 请求与保持条件:一个进程因请求资源而阻塞时,对已获得的资源保持不放。

  3. 不剥夺条件:进程已获得资源,在末使用完之前,不能强行剥夺。

  4. 循环等待条件:若干进程之间形成一种头尾相接的循环等待资源关系。

死锁的例子

public class Test { 
        public static void main(String[] args) { 
                DeadlockRisk dead = new DeadlockRisk(); 
                MyThread t1 = new MyThread(dead, 1, 2); 
                MyThread t2 = new MyThread(dead, 3, 4); 
                MyThread t3 = new MyThread(dead, 5, 6); 
                MyThread t4 = new MyThread(dead, 7, 8); 

                t1.start(); 
                t2.start(); 
                t3.start(); 
                t4.start(); 
        } 

} 

class MyThread extends Thread { 
        private DeadlockRisk dead; 
        private int a, b; 


        MyThread(DeadlockRisk dead, int a, int b) { 
                this.dead = dead; 
                this.a = a; 
                this.b = b; 
        } 

        @Override 
        public void run() { 
                dead.read(); 
                dead.write(a, b); 
        } 
} 

class DeadlockRisk { 
        private static class Resource { 
                public int value; 
        } 

        private Resource resourceA = new Resource(); 
        private Resource resourceB = new Resource(); 

        public int read() { 
                synchronized (resourceA) { 
                        System.out.println("read():" + Thread.currentThread().getName() + "获取了resourceA的锁!"); 
                        synchronized (resourceB) { 
                                System.out.println("read():" + Thread.currentThread().getName() + "获取了resourceB的锁!"); 
                                return resourceB.value + resourceA.value; 
                        } 
                } 
        } 

        public void write(int a, int b) { 
                synchronized (resourceB) { 
                        System.out.println("write():" + Thread.currentThread().getName() + "获取了resourceA的锁!"); 
                        synchronized (resourceA) { 
                                System.out.println("write():" + Thread.currentThread().getName() + "获取了resourceB的锁!"); 
                                resourceA.value = a; 
                                resourceB.value = b; 
                        } 
                } 
        } 
}
//运行结果
read():Thread-0获取了resourceA的锁!
read():Thread-0获取了resourceB的锁!
write():Thread-0获取了resourceA的锁!
read():Thread-3获取了resourceA的锁!

获取线程dump

  1. jps获得当前Java虚拟机进程的pid
    ➜ ~ jps
    657
    2564 Jps
    2525 AppMain
    2526 Launcher

  2. jstack打印堆栈
    Found one Java-level deadlock:
    =============================
    "Thread-3":
    waiting to lock monitor 0x00007fd5ca80c368 (object 0x00000007d56d1550, a deadlock.DeadlockRisk$Resource),
    which is held by "Thread-0"
    "Thread-0":
    waiting to lock monitor 0x00007fd5ca80ed58 (object 0x00000007d56d1540, a deadlock.DeadlockRisk$Resource),
    which is held by "Thread-3"

     Java stack information for the threads listed above:
     ===================================================
     "Thread-3":
             at deadlock.DeadlockRisk.read(Test.java:52)
             - waiting to lock <0x00000007d56d1550> (a deadlock.DeadlockRisk$Resource)
             - locked <0x00000007d56d1540> (a deadlock.DeadlockRisk$Resource)
             at deadlock.MyThread.run(Test.java:35)
     "Thread-0":
             at deadlock.DeadlockRisk.write(Test.java:62)
             - waiting to lock <0x00000007d56d1540> (a deadlock.DeadlockRisk$Resource)
             - locked <0x00000007d56d1550> (a deadlock.DeadlockRisk$Resource)
             at deadlock.MyThread.run(Test.java:36)
    
     Found 1 deadlock.
    

更多关于线程dump可以参考:http://my.oschina.net/u/161458/blog/266313

如何避免死锁

  1. 避免一个线程同时获取多个锁。

  2. 避免一个线程在锁内同时占用多个资源,尽量保证每个锁只占用一个资源。

  3. 尝试使用定时锁,使用lock.tryLock(timeout)来替代使用内部锁机制。

  4. 对于数据库锁,加锁和解锁必须在一个数据库连接里,否则会出现解锁失败的情况。

活锁

活锁:马路中间有条小桥,只能容纳一辆车经过,桥两头开来两辆车A和B,A比较礼貌,示意B先过,B也比较礼貌,示意A先过,结果两人一直谦让谁也过不去。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

  • 背景 10月2号凌晨12:08收到报警,所有请求失败,处于完全不可用状态 应用服务器共四台resin,resin之...
    AGIHunt阅读 22,323评论 6 16
  • 概述 线程本身由于创建和切换的开销,采用多线程不会提高程序的执行速度,反而会降低速度,但是对于频繁IO操作的程序,...
    wustor阅读 3,914评论 0 1
  • 20.1死锁概念 由于竞争资源或者通信关系,两个或更多线程在执行中出现,永远相互等待只能由其他进程引发的事件 进程...
    龟龟51阅读 3,895评论 0 1
  • 1、竞态条件: 定义:竞态条件指的是一种特殊的情况,在这种情况下各个执行单元以一种没有逻辑的顺序执行动作,从而导致...
    Hughman阅读 5,151评论 0 7
  • 死锁产生的原因和解锁的方法 产生死锁的四个必要条件: (1) 互斥条件:一个资源每次只能被一个进程使用。 (2) ...
    憩在河岸上的鱼丶阅读 5,348评论 0 4

友情链接更多精彩内容