java并发编程-一个简单的死锁示例和死锁的检查(代码片段)

Helios_Fz的学习笔记 Helios_Fz的学习笔记     2022-12-23     672

关键词:

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

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代码结构也会出现死锁,与嵌套不嵌套没有任何的关系。只要互相等待对方释放锁,就有可能出现死锁。

Java并发屏障示例死锁

】Java并发屏障示例死锁【英文标题】:Javaconcurrencybarrierexampledeadlock【发布时间】:2018-10-1107:42:17【问题描述】:我正在尝试实现自定义Barrier示例,以了解有关Java并发的更多信息。我有一个可运行的类:publicclassBarrierimplementsRunn... 查看详情

并发编程之死锁解析(代码片段)

前言在Java的并发编程中,有一个问题需要特别注意,那就是死锁,如果发生了死锁,基本就是重启,而重启将会丢失运行中的数据。所以,了解死锁的形成并排查死锁到预防死锁成了一个重要的问题。我们了解任何一个事情的... 查看详情

并发编程--锁--如何使用命令行和代码定位死锁

用命令行的方式找到死锁本地环境下,如果程序发生死锁后,首先cmd进入$JAVA_HOME/bin/中,输入jps命令,就可以查看到当前Java程序的pid,找到死锁类的pid后执行jstack命令+空格+死锁类的pid,就可以获取线程获取锁的信息。截取一部... 查看详情

java并发编程实战读书笔记之死锁(代码片段)

...二、动态的锁顺序死锁。前言本篇学习笔记源自于《Java并发编程实战》第10章。提示:以下是本篇文章正文内容,下面案例可供参考一、锁顺序死锁看下面代码,很容易造成死锁,leftRight和rightLeft方法分别获取了l... 查看详情

java并发编程实战读书笔记之死锁(代码片段)

...二、动态的锁顺序死锁。前言本篇学习笔记源自于《Java并发编程实战》第10章。提示:以下是本篇文章正文内容,下面案例可供参考一、锁顺序死锁看下面代码,很容易造成死锁,leftRight和rightLeft方法分别获取了l... 查看详情

java并发编程04:死锁

...善了系统资源的利用率并提高了系统的处理能力。然而,并发执行也带来了新的问题--死锁。所谓死锁是指多个线程因竞争资源而造成的一种僵局(互相等待),若无外力作用,这些进程都将无法向前推进。  2、死锁产出... 查看详情

java并发编程系列——死锁的解决(代码片段)

接下来我会以一个经典的转帐问题,跟大家一起聊聊死锁,以及如何解决这个问题。假如客户A需要给客户B转账,客户A的账户减少100元,客户B的账户增加100元。我们转化为代码描述:有一个账户类Account,... 查看详情

java并发编程系列——死锁的解决(代码片段)

接下来我会以一个经典的转帐问题,跟大家一起聊聊死锁,以及如何解决这个问题。假如客户A需要给客户B转账,客户A的账户减少100元,客户B的账户增加100元。我们转化为代码描述:有一个账户类Account,... 查看详情

[并发编程]产生死锁的——四大必要条件和解决方案(代码片段)

[什么是死锁?]              什么是死锁?一般对“死”字使用,在我们日常生活中都是极其避讳的,而这字偏偏又搭上一个“锁”字,就好像你永远也不可能解开你暗恋女神心中的那把锁一样...    ... 查看详情

python并发编程之死锁

前言在并发编程中,死锁指的是一种特定的情况,即无法取得进展,程序被锁定在其当前状态。在大多数情况下,这种现象是由于不同的锁对象(用于线程同步)之间缺乏协调,或者处理不当造成的。在这一节中,我们将讨论一... 查看详情

java多线程并发环境下的synchronized死锁实例(代码片段)

Java多线程并发环境下的synchronized死锁实例Java并发多线程环境中,造成死锁的最简单的场景是:多线程中的一个线程T_A持有锁L1并且申请试图获得锁L2;而多线程中另外一个线程T_B持有锁L2并且试图申请获得锁L1。线程... 查看详情

死锁的简单示例

...下去。产生死锁的四个必要条件:(1) 互斥条件:一个资源每次只能被一个进程使用。(2) 请求与保持条件:一个进程因请求资源而阻塞时,对已获得的资源保持不放。(3) 不剥夺条件:进程已获得的资源,在末... 查看详情

(更新中)谈谈个人对java并发编程中(管程模型,死锁,线程生命周期等问题)见解

... 公司的项目开始用到多线程,所以自己谈谈个人对于并发编程的见解。 并发编程会导致线程不安全,常说的线程不安全指的是 多个线程操作一个共享数据,导致线程之间的读取到的数据不一致。并发编程导致线程不... 查看详情

java并发编程:死锁(含代码)

JAVA大数据中高级架构2018-11-1014:04:32当线程需要同时持有多个锁时,有可能产生死锁。考虑如下情形:线程A当前持有互斥所锁lock1,线程B当前持有互斥锁lock2。接下来,当线程A仍然持有lock1时,它试图获取lock2,因为线程B正持有lo... 查看详情

juc并发编程活跃性--死锁&定位死锁&哲学家就餐问题(代码片段)

1.死锁有这样的情况:一个线程需要同时获取多把锁,这时就容易发生死锁示例:t1线程获得A对象锁,接下来想获取B对象的锁t2线程获得B对象锁,接下来想获取A对象的锁packagetian;importlombok.extern.slf4j.Slf4j;@Slf4j(topi... 查看详情

day825.死锁问题-java并发编程实战(代码片段)

...解决银行业务里面的转账问题,虽然这个方案不存在并发问题,但是所有账户的转账操作都是串行的,例如账户A转账户B、账户C转账户D这两个转账操作现实世界里是可以并行的,但是在这个方案里却被串行化了&#x... 查看详情

day825.死锁问题-java并发编程实战(代码片段)

...解决银行业务里面的转账问题,虽然这个方案不存在并发问题,但是所有账户的转账操作都是串行的,例如账户A转账户B、账户C转账户D这两个转账操作现实世界里是可以并行的,但是在这个方案里却被串行化了&#x... 查看详情

深入了解java并发——《javaconcurrencyinpractice》10.避免活跃性危险

死锁是并发编程中最容易遇到的活跃性问题,本章就死锁发生的原因、诊断、避免死锁的方案进行了细致的解读。10.1死锁在线程A持有锁L并想获得锁M的同时,线程B持有锁M并尝试获得锁L,那么这两个线程将永远的等... 查看详情