zoukankan      html  css  js  c++  java
  • 并发死锁

    JVM可以检测到synchronized导致的死锁,考虑下面的代码:

    public class ClassA {
        public static String monitor1 = "monitor1";
        public static String monitor2 = "monitor2";
        public static void main(String[] args) {
            Thread thread1 = new Thread(new Runnable() {
                public void run() {
                    try {
                        synchronized (monitor1) {
                            System.out.println(Thread.currentThread().getName() + ": got monitor1");
                            Thread.sleep(5000);
                            synchronized (monitor2) {
                                System.out.println(Thread.currentThread().getName() + ": got monitor2");
                            }
                        }
                    } catch (InterruptedException e) {}
                }
            }, "I'm Thread1");
            thread1.start();
            Thread thread2 = new Thread(new Runnable() {
                public void run() {
                    try {
                        synchronized (monitor2) {
                            System.out.println(Thread.currentThread().getName() + ": got monitor2");
                            Thread.sleep(5000);
                            synchronized (monitor1) {
                                System.out.println(Thread.currentThread().getName() + ": got monitor1");
                            }
                        }
                    } catch (InterruptedException e) {}
                }
            }, "I'm Thread2");
            thread2.start();
        }
    }


    代码中有意制造了典型的死锁情况,即在持有资源的情况下请求新的资源,并且两个线程交叉请求资源,从而导致在特定情况下发生死锁。

    在JVM监测中可以明显看到死锁并可以准确定位造成死锁的代码,如下图:

    image

    继续进行Thread Dump,在Thread Dump中发现错误代码的位置,如下图:

    其中明确说明了造成死锁的原因。

    上面描述的死锁是有意制造的简单场景,实际系统中的情况通常复杂得多,因此在开发过程中synchronized的使用应该谨慎,因为死锁很容易监测出来,但无法在JVM运行过程中简单地处理死锁。

    Java开发过程中,无论是使用synchronized关键字,还是使用其他锁定机制(如java.util.concurrent.locks.*)中的方法,在编程错误的情况下都可能出现死锁。死锁是操作系统课程中的重要内容,在多线程环境中编程的程序员应该了解其概念及如何避免死锁。

    附:死锁产生的必要条件

    如果在系统中同时具备下面四个必要条件时,那么可能发生死锁。换句话说,只要下面四个条件有一个不具备,系统就不会出现死锁。

    • 互斥条件:即某个资源在一段时间内只能由一个进程占有,不能同时被两个或两个以上的进程占有。这种独占资源如CD-ROM驱动器,打印机等等,必须在占有该资源的进程主动释放它之后,其它进程才能占有该资源。这是由资源本身的属性所决定的。如打印机就是一种独占资源,两份文档不能同时打印;
    • 不可抢占条件:进程所获得的资源在未使用完毕之前,资源申请者不能强行地从资源占有者手中夺取资源,而只能由该资源的占有者进程自行释放;
    • 占有且申请条件:进程至少已经占有一个资源,但又申请新的资源;由于该资源已被另外进程占有,此时该进程阻塞;但是,它在等待新资源之时,仍继续占用已占有的资源;
    • 循环等待条件:存在一个进程等待序列{P1,P2,...,Pn},其中P1等待P2所占有的某一资源,P2等待P3所占有的某一源,......,而Pn等待P1所占有的的某一资源,形成一个进程循环等待环;

    上面四个条件在死锁时会同时发生。也就是说,只要有一个必要条件不满足,则死锁就可以排除。

  • 相关阅读:
    org.springframework.web.servlet.mvc.multiaction.NoSuchRequestHandlingMethodException
    Mybatis分页插件PageHelper使用
    比特大陆发布终端 AI 芯片 端云联手聚焦安防
    大数据相乘
    MyBatis学习 之 二、SQL语句映射文件(1)resultMap
    MyBatis学习 之 一、MyBatis简介与配置MyBatis+Spring+MySql
    MyBatis学习 之 一、MyBatis简介与配置MyBatis+Spring+MySql
    MyBatis学习 之 四、MyBatis配置文件
    MyBatis学习 之 四、MyBatis配置文件
    xgqfrms™, xgqfrms® : xgqfrms's offical website of GitHub!
  • 原文地址:https://www.cnblogs.com/xiongmaotailang/p/5249712.html
Copyright © 2011-2022 走看看