zoukankan      html  css  js  c++  java
  • Java并发编程

      一个简单的死锁示例和死锁的检查

    Java线程死锁是一个经典的多线程问题。因为不同的线程都在等待根本不可能被释放的锁,从而导致所有的任务都无法继续完成。

    1.死锁程序示例

    创建类 DeadLockThread:

    public class DeadLockThread implements Runnable {
    
        private Object lock1 = new Object();
        private Object lock2 = new Object();
    
        private String s;
    
        public void setS(String s) {
            this.s = s;
        }
    
        @Override
        public void run() {
            if ("a".equalsIgnoreCase(s)) {
                synchronized (lock1) {
                    System.out.println(Thread.currentThread() + " a 正在执行");
                    try {
                        Thread.sleep(3000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    synchronized (lock2) {
                        System.out.println("lock1 -> lock2 死锁未生效");
                    }
                }
            }
            if ("b".equalsIgnoreCase(s)) {
                synchronized (lock2) {
                    System.out.println(Thread.currentThread() + " b 正在执行");
                    try {
                        Thread.sleep(3000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    synchronized (lock1) {
                        System.out.println("lock2 -> lock1 死锁未生效");
                    }
                }
            }
        }
    }

    创建运行类 Main:

    public class Main {
    
        public static void main(String[] args) throws InterruptedException {
            DeadLockThread deadLockThread = new DeadLockThread();
    
            deadLockThread.setS("a");
            Thread threadA = new Thread(deadLockThread);
            threadA.start();
            Thread.sleep(200);
    
            deadLockThread.setS("b");
            Thread threadB = new Thread(deadLockThread);
            threadB.start();
            Thread.sleep(200);
        }
    }

    运行结果如下:

     2.使用JDK自带工具做死锁后的检查

    1.进入JDK安装文件夹中的bin目录,执行jps命令:

     得到正在运行着的线程Main的id值是12295。

    2.在执行 jstack -l 12295 命令,查看结果:

    由此结果可知,程序有死锁的现象。

    3.使用IDEA的FindBugs插件检查可能出现的死锁

    右键测试代码所在的包,选择分析包内文件

     分析结果如下:

    This method calls Thread.sleep() with a lock held. 
    This may result in very poor performance and scalability, or a deadlock, since other threads may be waiting to acquire the lock. 
    It is a much better idea to call wait() on the lock, which releases the lock and allows other threads to run.
    此方法调用thread.sleep(),并保留一个锁。
    这可能会导致性能和可伸缩性非常差,或者出现死锁,因为其他线程可能正在等待获取锁。
    最好对锁调用wait(),这样可以释放锁并允许其他线程运行。

      

    死锁是程序设计的bug,在设计程序时要避免双方互相持有对方锁的情况。需要说明的是,本实验使用synchronized嵌套的代码结构来实现死锁,其实不使用嵌套的synchronized代码结构也会出现死锁,与嵌套不嵌套没有任何的关系。只要互相等待对方释放锁,就有可能出现死锁。

  • 相关阅读:
    Redis为什么使用单进程单线程方式也这么快
    高性能IO模型浅析
    计算机基础知识_硬件知识
    计算机基础知识_进制转化
    计算机基础知识
    C语言_第一讲_C语言入门
    C语言_第二讲_规范以及常用数据类型
    COM_第四讲_保存GUID_优化使用代码
    4.性能下降原因和常见的Join查询
    3.MySQL的架构介绍
  • 原文地址:https://www.cnblogs.com/helios-fz/p/11663518.html
Copyright © 2011-2022 走看看