死锁示例代码

Deadlock in java is a programming situation where two or more threads are blocked forever. Java deadlock situation arises with at least two threads and two or more resources. Here I have written a simple program that will cause java deadlock scenario and then we will see how to analyze it.

Java中的死锁是一种编程情况,其中两个或多个线程被永久阻止。 Java死锁情况发生在至少两个线程和两个或更多资源的情况下。 在这里,我编写了一个简单的程序,它将导致java死锁的情况,然后我们将看到如何对其进行分析。

Java中的死锁 (Deadlock in Java)

Let’s have a look at a simple program where I will create deadlock in java threads.

让我们看一个简单的程序,在该程序中我将在Java线程中创建死锁。

package com.journaldev.threads;public class ThreadDeadlock {public static void main(String[] args) throws InterruptedException {Object obj1 = new Object();Object obj2 = new Object();Object obj3 = new Object();Thread t1 = new Thread(new SyncThread(obj1, obj2), "t1");Thread t2 = new Thread(new SyncThread(obj2, obj3), "t2");Thread t3 = new Thread(new SyncThread(obj3, obj1), "t3");t1.start();Thread.sleep(5000);t2.start();Thread.sleep(5000);t3.start();}}class SyncThread implements Runnable{private Object obj1;private Object obj2;public SyncThread(Object o1, Object o2){this.obj1=o1;this.obj2=o2;}@Overridepublic void run() {String name = Thread.currentThread().getName();System.out.println(name + " acquiring lock on "+obj1);synchronized (obj1) {System.out.println(name + " acquired lock on "+obj1);work();System.out.println(name + " acquiring lock on "+obj2);synchronized (obj2) {System.out.println(name + " acquired lock on "+obj2);work();}System.out.println(name + " released lock on "+obj2);}System.out.println(name + " released lock on "+obj1);System.out.println(name + " finished execution.");}private void work() {try {Thread.sleep(30000);} catch (InterruptedException e) {e.printStackTrace();}}
}

In above program SyncThread is implementing Runnable interface and it works on two Objects by acquiring lock on each one of them one by one using synchronized block.

在上面的程序中,SyncThread实现了Runnable接口,并且通过使用同步块一个接一个地获取对每个对象的锁定,从而对两个对象起作用。

In main method, I have three threads running for SyncThread and there is a shared resource between each of the threads. The threads are run in such a way that it will be able to acquire lock on the first object but when it’s trying to acquire lock on second object, it goes on wait state because it’s already locked by another thread. This forms a cyclic dependency for resource between Threads causing deadlock.

在main方法中,我为SyncThread运行了三个线程,并且每个线程之间都有一个共享资源。 线程以这样的方式运行:它将能够获取第一个对象上的锁,但是当它试图获取第二个对象上的锁时,它将进入等待状态,因为它已经被另一个线程锁定了。 这对导致死锁的线程之间的资源形成了循环依赖性。

When I execute the above program, here is the output generated but program never terminates because of deadlock in java threads.

当我执行上面的程序时,这里是生成的输出,但是由于Java线程中的死锁,程序永远不会终止。

t1 acquiring lock on java.lang.Object@6d9dd520
t1 acquired lock on java.lang.Object@6d9dd520
t2 acquiring lock on java.lang.Object@22aed3a5
t2 acquired lock on java.lang.Object@22aed3a5
t3 acquiring lock on java.lang.Object@218c2661
t3 acquired lock on java.lang.Object@218c2661
t1 acquiring lock on java.lang.Object@22aed3a5
t2 acquiring lock on java.lang.Object@218c2661
t3 acquiring lock on java.lang.Object@6d9dd520

Here we can clearly identify the deadlock situation from the output but in real life applications it’s very hard to find the deadlock situation and debug them.

在这里,我们可以从输出中清楚地确定死锁情况,但是在实际应用中,很难找到死锁情况并对其进行调试。

如何在Java中检测死锁 (How to Detect Deadlock in Java)

To detect a deadlock in java, we need to look at the java thread dump of the application, in last post I explained how we can generate thread dump using VisualVM profiler or using jstack utility.

要检测Java中的死锁,我们需要查看应用程序的Java线程转储 ,在上一篇文章中,我解释了如何使用VisualVM Profiler或jstack实用程序生成线程转储。

Here is the thread dump of above program.

这是上面程序的线程转储。

2012-12-27 19:08:34
Full thread dump Java HotSpot(TM) 64-Bit Server VM (23.5-b02 mixed mode):"Attach Listener" daemon prio=5 tid=0x00007fb0a2814000 nid=0x4007 waiting on condition [0x0000000000000000]java.lang.Thread.State: RUNNABLE"DestroyJavaVM" prio=5 tid=0x00007fb0a2801000 nid=0x1703 waiting on condition [0x0000000000000000]java.lang.Thread.State: RUNNABLE"t3" prio=5 tid=0x00007fb0a204b000 nid=0x4d07 waiting for monitor entry [0x000000015d971000]java.lang.Thread.State: BLOCKED (on object monitor)at com.journaldev.threads.SyncThread.run(ThreadDeadlock.java:41)- waiting to lock <0x000000013df2f658> (a java.lang.Object)- locked <0x000000013df2f678> (a java.lang.Object)at java.lang.Thread.run(Thread.java:722)"t2" prio=5 tid=0x00007fb0a1073000 nid=0x4207 waiting for monitor entry [0x000000015d209000]java.lang.Thread.State: BLOCKED (on object monitor)at com.journaldev.threads.SyncThread.run(ThreadDeadlock.java:41)- waiting to lock <0x000000013df2f678> (a java.lang.Object)- locked <0x000000013df2f668> (a java.lang.Object)at java.lang.Thread.run(Thread.java:722)"t1" prio=5 tid=0x00007fb0a1072000 nid=0x5503 waiting for monitor entry [0x000000015d86e000]java.lang.Thread.State: BLOCKED (on object monitor)at com.journaldev.threads.SyncThread.run(ThreadDeadlock.java:41)- waiting to lock <0x000000013df2f668> (a java.lang.Object)- locked <0x000000013df2f658> (a java.lang.Object)at java.lang.Thread.run(Thread.java:722)"Service Thread" daemon prio=5 tid=0x00007fb0a1038000 nid=0x5303 runnable [0x0000000000000000]java.lang.Thread.State: RUNNABLE"C2 CompilerThread1" daemon prio=5 tid=0x00007fb0a1037000 nid=0x5203 waiting on condition [0x0000000000000000]java.lang.Thread.State: RUNNABLE"C2 CompilerThread0" daemon prio=5 tid=0x00007fb0a1016000 nid=0x5103 waiting on condition [0x0000000000000000]java.lang.Thread.State: RUNNABLE"Signal Dispatcher" daemon prio=5 tid=0x00007fb0a4003000 nid=0x5003 runnable [0x0000000000000000]java.lang.Thread.State: RUNNABLE"Finalizer" daemon prio=5 tid=0x00007fb0a4800000 nid=0x3f03 in Object.wait() [0x000000015d0c0000]java.lang.Thread.State: WAITING (on object monitor)at java.lang.Object.wait(Native Method)- waiting on <0x000000013de75798> (a java.lang.ref.ReferenceQueue$Lock)at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:135)- locked <0x000000013de75798> (a java.lang.ref.ReferenceQueue$Lock)at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:151)at java.lang.ref.Finalizer$FinalizerThread.run(Finalizer.java:177)"Reference Handler" daemon prio=5 tid=0x00007fb0a4002000 nid=0x3e03 in Object.wait() [0x000000015cfbd000]java.lang.Thread.State: WAITING (on object monitor)at java.lang.Object.wait(Native Method)- waiting on <0x000000013de75320> (a java.lang.ref.Reference$Lock)at java.lang.Object.wait(Object.java:503)at java.lang.ref.Reference$ReferenceHandler.run(Reference.java:133)- locked <0x000000013de75320> (a java.lang.ref.Reference$Lock)"VM Thread" prio=5 tid=0x00007fb0a2049800 nid=0x3d03 runnable "GC task thread#0 (ParallelGC)" prio=5 tid=0x00007fb0a300d800 nid=0x3503 runnable "GC task thread#1 (ParallelGC)" prio=5 tid=0x00007fb0a2001800 nid=0x3603 runnable "GC task thread#2 (ParallelGC)" prio=5 tid=0x00007fb0a2003800 nid=0x3703 runnable "GC task thread#3 (ParallelGC)" prio=5 tid=0x00007fb0a2004000 nid=0x3803 runnable "GC task thread#4 (ParallelGC)" prio=5 tid=0x00007fb0a2005000 nid=0x3903 runnable "GC task thread#5 (ParallelGC)" prio=5 tid=0x00007fb0a2005800 nid=0x3a03 runnable "GC task thread#6 (ParallelGC)" prio=5 tid=0x00007fb0a2006000 nid=0x3b03 runnable "GC task thread#7 (ParallelGC)" prio=5 tid=0x00007fb0a2006800 nid=0x3c03 runnable "VM Periodic Task Thread" prio=5 tid=0x00007fb0a1015000 nid=0x5403 waiting on condition JNI global references: 114Found one Java-level deadlock:
=============================
"t3":waiting to lock monitor 0x00007fb0a1074b08 (object 0x000000013df2f658, a java.lang.Object),which is held by "t1"
"t1":waiting to lock monitor 0x00007fb0a1010f08 (object 0x000000013df2f668, a java.lang.Object),which is held by "t2"
"t2":waiting to lock monitor 0x00007fb0a1012360 (object 0x000000013df2f678, a java.lang.Object),which is held by "t3"Java stack information for the threads listed above:
===================================================
"t3":at com.journaldev.threads.SyncThread.run(ThreadDeadlock.java:41)- waiting to lock <0x000000013df2f658> (a java.lang.Object)- locked <0x000000013df2f678> (a java.lang.Object)at java.lang.Thread.run(Thread.java:722)
"t1":at com.journaldev.threads.SyncThread.run(ThreadDeadlock.java:41)- waiting to lock <0x000000013df2f668> (a java.lang.Object)- locked <0x000000013df2f658> (a java.lang.Object)at java.lang.Thread.run(Thread.java:722)
"t2":at com.journaldev.threads.SyncThread.run(ThreadDeadlock.java:41)- waiting to lock <0x000000013df2f678> (a java.lang.Object)- locked <0x000000013df2f668> (a java.lang.Object)at java.lang.Thread.run(Thread.java:722)Found 1 deadlock.

The thread dump output clearly shows the deadlock situation and threads and resources involved causing deadlock situation.

线程转储输出清楚地显示了死锁情况,并且所涉及的线程和资源导致了死锁情况。

For analyzing deadlock, we need to look out for the threads with state as BLOCKED and then the resources it’s waiting to lock. Every resource has a unique ID using which we can find which thread is already holding the lock on the object. For example Thread “t3” is waiting to lock 0x000000013df2f658 but it’s already locked by thread “t1”.

为了分析死锁,我们需要寻找状态为BLOCKED的线程,然后寻找其等待锁定的资源。 每个资源都有一个唯一的ID,通过它我们可以找到哪个线程已经对该对象进行了锁定。 例如,线程“ t3”正在等待锁定0x000000013df2f658,但它已被线程“ t1”锁定。

Once we analyze the deadlock situation and found out the threads which are causing deadlock, we need to make code changes to avoid deadlock situation.

一旦分析了死锁情况并找出了导致死锁的线程,就需要进行代码更改以避免死锁情况。

如何避免Java中的死锁 (How to avoid deadlock in java)

These are some of the guidelines using which we can avoid most of the deadlock situations.

这些是我们可以避免大多数僵局情况的一些准则。

  • Avoid Nested Locks: This is the most common reason for deadlocks, avoid locking another resource if you already hold one. It’s almost impossible to get deadlock situation if you are working with only one object lock. For example, here is the another implementation of run() method without nested lock and program runs successfully without deadlock situation.

    public void run() {String name = Thread.currentThread().getName();System.out.println(name + " acquiring lock on " + obj1);synchronized (obj1) {System.out.println(name + " acquired lock on " + obj1);work();}System.out.println(name + " released lock on " + obj1);System.out.println(name + " acquiring lock on " + obj2);synchronized (obj2) {System.out.println(name + " acquired lock on " + obj2);work();}System.out.println(name + " released lock on " + obj2);System.out.println(name + " finished execution.");}

    避免嵌套锁 :这是导致死锁的最常见原因,如果已经持有另一个资源,请避免锁定另一个资源。 如果仅使用一个对象锁,则几乎不可能出现死锁情况。 例如,这是不带嵌套锁的run()方法的另一种实现,并且程序成功运行且没有死锁情况。

  • Lock Only What is Required: You should acquire lock only on the resources you have to work on, for example in above program I am locking the complete Object resource but if we are only interested in one of it’s fields, then we should lock only that specific field not complete object.仅锁定所需条件 :您应该仅对必须处理的资源获取锁定,例如,在上述程序中,我正在锁定完整的Object资源,但是如果我们仅对其中一个字段感兴趣,则应该仅锁定该对象具体字段不完整的对象。
  • Avoid waiting indefinitely: You can get deadlock if two threads are waiting for each other to finish indefinitely using thread join. If your thread has to wait for another thread to finish, it’s always best to use join with maximum time you want to wait for thread to finish.避免无限期地等待 :如果两个线程正在使用线程连接无限期地等待彼此完成,则可能会陷入死锁。 如果您的线程必须等待另一个线程完成,则始终最好使用join并在等待线程完成的最长时间内使用它。

That’s all for deadlock in java threads.

这就是Java线程中的死锁。

翻译自: https://www.journaldev.com/1058/deadlock-in-java-example

死锁示例代码

死锁示例代码_Java示例中的死锁相关推荐

  1. java线程中的死锁_Java多线程中的死锁 - Break易站

    Java 多线程 synchronized关键字用于使类或方法线程安全,这意味着只有一个线程可以锁定同步方法并使用它,其他线程必须等到锁定释放并且其中任何一个获得该锁定. 如果我们的程序在多线程环境中 ...

  2. 迭代器设计模式(Iterator Design Pattern)[论点:概念、组成角色、相关图示、示例代码、框架中的运用、适用场景]

    概念 迭代器设计模式(Iterator Design Pattern)是一种行为型设计模式,它提供了一种方法来顺序访问一个聚合对象(如集合)的元素,而不需要暴露该对象的底层表示.迭代器模式可以帮助我们 ...

  3. 质疑贴——对《新版微软一站式示例代码库》中的一个示例的质疑

    在"新版微软一站式示例代码库发布 - 绑定第三版示例代码浏览器"中,有若干最新的asp.net的示例. 对其中的一个示例的源代码研究了一番.觉得有问题,故在此阐述本人的疑问,望广大 ...

  4. sql server死锁_了解SQL Server中的死锁图的XML描述

    sql server死锁 介绍 (Introduction) 在我的前两篇文章" What is a SQL Server Deadlock and 什么是SQL Server死锁" ...

  5. sql server死锁_了解SQL Server中的死锁定义

    sql server死锁 This article explains the deadlock definition in SQL Server, and it also mentions how t ...

  6. 【数据分析学习笔记day09】数据分析实战案例:2016美国大选民意调查统计+2016年美国总统大选民意调查数据统计+示例代码1 +示例代码2:

    文章目录 2016年美国大选民意调查数据统计: 示例代码1 : 示例代码2: 2016年美国大选民意调查数据统计: 项目地址:https://www.kaggle.com/fivethirtyeigh ...

  7. java方法示例注释 @_Java 8中的功能接口是什么? @功能注释和示例

    java方法示例注释 @ 函数接口是Java 8最重要的概念之一,实际上为lambda表达式提供了动力,但是许多开发人员没有首先了解函数接口在Java 8中的作用就花了很多精力来理解它,并花时间学习l ...

  8. 状态设计模式(State Pattern)[论点:概念、相关角色、图示、示例代码、框架中的运用、适用场景]

    文章目录 概念 组成角色 相关图示 代码示例 框架中的应用 适用场景 概念 状态模式(State Pattern)是一种行为型设计模式,用于解决对象在不同状态下的行为问题.它允许一个对象在其内部状态改 ...

  9. Java电子辞典笔记代码_Java 示例代码笔记(遗忘点)

    1.trim() Scanner scanner=new Scanner(System.in); String s=scanner.nextLine(); //s=" SherlyHan & ...

最新文章

  1. Android SDK Tools Setup 提示 “ java se development kit not found”
  2. Android TabWidget
  3. UA MATH564 概率论 依概率收敛的一个例题
  4. Python—进程、线程、协程
  5. C#中'??'符的使用
  6. iOS - 判断用户是否允许推送通知(iOS7/iOS8)
  7. php curl_error源码,PHP curl_error函数
  8. 玩转Nacos参数配置!多图勿点
  9. 判断整除(信息学奥赛一本通-T1195)
  10. ThreadLocal 在web环境下使用的边界问题
  11. 基于Servlet的技术问答网站系统实现(附源码)
  12. python 与或非_Java、PHP和Python各有什么优势 分别能做什么
  13. 求10 个整数中最大值
  14. EasyRecovery如何恢复ps的psd文件
  15. MySQL学习(一、概述和表的基本操作)
  16. Excel自定义格式详解
  17. 网易2020校招数据分析方向正式批笔试题 解析
  18. Win10账户已被锁定解决方法
  19. 关于struts.xml的配置思考。
  20. java retrofit2_Java Retrofit2使用

热门文章

  1. error parsing xml:unbound prefix
  2. iphone开发中图像处理相关要点
  3. C++ 引用的几个用法
  4. [转载] numpy教程:矩阵matrix及其运算
  5. [置顶] android 与JavaScript的互相调用
  6. [BZOJ2440][中山市选2011]完全平方数(莫比乌斯函数,二分)
  7. 单点登录实现机制:web-sso
  8. javascript div 弹出可拖动窗口
  9. JQGrid 嵌套字表, json数据
  10. zz 传苹果平板电脑的UI界面将具备“快速学习”功能