Java死锁浅析

什么是死锁?

        死锁是指两个或两个以上的线程在执行过程中,因争夺资源而造成的互相等待的现象,若无外力干涉则都无法继续推进。如果系统资源充足,线程的资源请求都能够得到满足,死锁出现的可能性就很低,否则就会因争夺有限的资源而陷入死锁。

                    

像上面这种,线程A持有锁A并尝试获取锁B,线程B持有锁B并尝试获取锁A,造成死锁。

产生死锁的主要原因:

  • 系统资源不足
  • 进程运行推进的顺序不合适
  • 资源分配不当

1、举例死锁

class MyLockData implements Runnable{
    private String mLockA;
    private String mLockB;

    public MyLockData(String mLockA, String mLockB) {
        this.mLockA = mLockA;
        this.mLockB = mLockB;
    }

    @Override
    public void run() {
        synchronized (mLockA){
            System.out.println(Thread.currentThread().getName() + " 持有:"+mLockA+"    并申请锁:"+mLockB);
            try {
                TimeUnit.SECONDS.sleep(2L);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            synchronized (mLockB){
                System.out.println(Thread.currentThread().getName() + " 持有:"+mLockB+"    并申请锁:"+mLockA);
            }
        }
    }
}
public class MyLockDemo {

    public static void main(String[] args) {
        final MyLockData data = new MyLockData("α锁","β锁");
        final MyLockData data2 = new MyLockData("β锁","α锁");
        new Thread(new Runnable() {
            @Override
            public void run() {
                data.run();
            }
        },"线程A").start();

        new Thread(new Runnable() {
            @Override
            public void run() {
                data2.run();
            }
        },"线程B").start();
    }
}

--------------------
线程A 持有:α锁    并申请锁:β锁
线程B 持有:β锁    并申请锁:α锁

2、证明死锁

     windows下的进程查看命令:

  • jps -l:可以查看有问题的类及其进程编号;
  • jstack xxxx:xxxx就是上一步查询出来的进程编号,可以查看该类下的具体问题所在。

     2.1、运行程序,进入“死锁”状态;

     2.2、在控制台 Terminal 栏输入命令:jps -l,查看哪些类有问题,

             

     2.3、接着输入命令:jstack -7424,查看这个类到底出了什么问题

             

               Found 1 deadlock.   原因,红框部分一目了然。

3.解决死锁

      根据上一步找到死锁的原因,找到相关代码进行整理优化,重启服务器。

猜你喜欢

转载自blog.csdn.net/S_Alics/article/details/103052752