Java多线程死锁例子

目录

  • 一、产生死锁的原因
  • 二、如何避免死锁

一、产生死锁的原因

发生死锁的情况: 多个线程需要同时占用多个共享资源而发生需要互相死循环等待的情况,就是,两个线程互相等待着对象释放锁,一直这样僵持下去,所以导致了死锁的产生。

产生死锁代码:

package com.javaagent.thread;public class DieThread implements Runnable {public static Object obj1=new Object();public static Object obj2=new Object();private boolean flag;public DieThread(boolean bl){flag = bl;}@Overridepublic void run() {if(flag) {while(true) {synchronized(obj1) {try {Thread.sleep(1000);}catch (InterruptedException e){e.printStackTrace();}System.out.println("线程" + Thread.currentThread().getName() + "获取obj1锁对象,等待获取obj2锁对象...");synchronized(obj2) {System.out.println(Thread.currentThread().getName() + " ---- obj2.");}}}}else {while(true){synchronized(obj2) {System.out.println("线程" + Thread.currentThread().getName() + "获取obj2锁对象,等待获取obj1锁对象...");synchronized(obj1) {System.out.println(Thread.currentThread().getName() + " ---- obj1.");}}}}}
}
public class Main {public static void main(String[] args){DieThread d1=new DieThread(true);DieThread d2=new DieThread(false);final Thread t1 = new Thread(d1);final Thread t2 = new Thread(d2);t1.setName("DieThread_1");t2.setName("DieThread_2");t1.start();t2.start();}
}

输出结果:

线程DieThread_2获取obj2锁对象,等待获取obj1锁对象...
线程DieThread_1获取obj1锁对象,等待获取obj2锁对象...

采用 visualVM工具 来进行诊断,结果如下图所示:
在这里插入图片描述
从该图中,我们可以看出,Main的 进程ID为84114 ,红框1中提示 检测到死锁 ,然后我们点击红框3来查看 线程Dump 数据,如下图:
在这里插入图片描述
详细信息:

2020-03-04 15:02:44
Full thread dump Java HotSpot(TM) 64-Bit Server VM (25.121-b13 mixed mode):"RMI TCP Connection(idle)" #19 daemon prio=9 os_prio=31 tid=0x00007ff1db108800 nid=0x5f03 waiting on condition [0x0000700001961000]java.lang.Thread.State: TIMED_WAITING (parking)at sun.misc.Unsafe.park(Native Method)- parking to wait for  <0x0000000796082e28> (a java.util.concurrent.SynchronousQueue$TransferStack)at java.util.concurrent.locks.LockSupport.parkNanos(LockSupport.java:215)at java.util.concurrent.SynchronousQueue$TransferStack.awaitFulfill(SynchronousQueue.java:460)at java.util.concurrent.SynchronousQueue$TransferStack.transfer(SynchronousQueue.java:362)at java.util.concurrent.SynchronousQueue.poll(SynchronousQueue.java:941)at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1066)at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1127)at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)at java.lang.Thread.run(Thread.java:745)Locked ownable synchronizers:- None"JMX server connection timeout 18" #18 daemon prio=9 os_prio=31 tid=0x00007ff1da87c800 nid=0x5d03 in Object.wait() [0x000070000185e000]java.lang.Thread.State: TIMED_WAITING (on object monitor)at java.lang.Object.wait(Native Method)at com.sun.jmx.remote.internal.ServerCommunicatorAdmin$Timeout.run(ServerCommunicatorAdmin.java:168)- locked <0x00000007964a9dc8> (a [I)at java.lang.Thread.run(Thread.java:745)Locked ownable synchronizers:- None"RMI Scheduler(0)" #17 daemon prio=9 os_prio=31 tid=0x00007ff1da895800 nid=0x5b03 waiting on condition [0x000070000175b000]java.lang.Thread.State: TIMED_WAITING (parking)at sun.misc.Unsafe.park(Native Method)- parking to wait for  <0x00000007960ab5d8> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject)at java.util.concurrent.locks.LockSupport.parkNanos(LockSupport.java:215)at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.awaitNanos(AbstractQueuedSynchronizer.java:2078)at java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(ScheduledThreadPoolExecutor.java:1093)at java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(ScheduledThreadPoolExecutor.java:809)at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1067)at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1127)at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)at java.lang.Thread.run(Thread.java:745)Locked ownable synchronizers:- None"RMI TCP Connection(1)-10.0.5.39" #16 daemon prio=9 os_prio=31 tid=0x00007ff1d99ed800 nid=0x5903 runnable [0x0000700001657000]java.lang.Thread.State: RUNNABLEat java.net.SocketInputStream.socketRead0(Native Method)at java.net.SocketInputStream.socketRead(SocketInputStream.java:116)at java.net.SocketInputStream.read(SocketInputStream.java:171)at java.net.SocketInputStream.read(SocketInputStream.java:141)at java.io.BufferedInputStream.fill(BufferedInputStream.java:246)at java.io.BufferedInputStream.read(BufferedInputStream.java:265)- locked <0x00000007963eced8> (a java.io.BufferedInputStream)at java.io.FilterInputStream.read(FilterInputStream.java:83)at sun.rmi.transport.tcp.TCPTransport.handleMessages(TCPTransport.java:550)at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run0(TCPTransport.java:826)at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.lambda$run$0(TCPTransport.java:683)at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler$$Lambda$3/657644190.run(Unknown Source)at java.security.AccessController.doPrivileged(Native Method)at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(TCPTransport.java:682)at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)at java.lang.Thread.run(Thread.java:745)Locked ownable synchronizers:- <0x0000000796299c10> (a java.util.concurrent.ThreadPoolExecutor$Worker)"RMI TCP Accept-0" #15 daemon prio=9 os_prio=31 tid=0x00007ff1d9941800 nid=0x570f runnable [0x0000700001555000]java.lang.Thread.State: RUNNABLEat java.net.PlainSocketImpl.socketAccept(Native Method)at java.net.AbstractPlainSocketImpl.accept(AbstractPlainSocketImpl.java:409)at java.net.ServerSocket.implAccept(ServerSocket.java:545)at java.net.ServerSocket.accept(ServerSocket.java:513)at sun.management.jmxremote.LocalRMIServerSocketFactory$1.accept(LocalRMIServerSocketFactory.java:52)at sun.rmi.transport.tcp.TCPTransport$AcceptLoop.executeAcceptLoop(TCPTransport.java:400)at sun.rmi.transport.tcp.TCPTransport$AcceptLoop.run(TCPTransport.java:372)at java.lang.Thread.run(Thread.java:745)Locked ownable synchronizers:- None"Attach Listener" #13 daemon prio=9 os_prio=31 tid=0x00007ff1db028800 nid=0x5303 waiting on condition [0x0000000000000000]java.lang.Thread.State: RUNNABLELocked ownable synchronizers:- None"DestroyJavaVM" #12 prio=5 os_prio=31 tid=0x00007ff1da1ac000 nid=0x1403 waiting on condition [0x0000000000000000]java.lang.Thread.State: RUNNABLELocked ownable synchronizers:- None"DieThread_2" #11 prio=5 os_prio=31 tid=0x00007ff1d9839800 nid=0x5103 waiting for monitor entry [0x000070000134f000]java.lang.Thread.State: BLOCKED (on object monitor)at com.javaagent.thread.DieThread.run(DieThread.java:37)- waiting to lock <0x000000079585bee0> (a java.lang.Object)- locked <0x000000079585bef0> (a java.lang.Object)at java.lang.Thread.run(Thread.java:745)Locked ownable synchronizers:- None"DieThread_1" #10 prio=5 os_prio=31 tid=0x00007ff1d9835800 nid=0x4f03 waiting for monitor entry [0x000070000124c000]java.lang.Thread.State: BLOCKED (on object monitor)at com.javaagent.thread.DieThread.run(DieThread.java:26)- waiting to lock <0x000000079585bef0> (a java.lang.Object)- locked <0x000000079585bee0> (a java.lang.Object)at java.lang.Thread.run(Thread.java:745)Locked ownable synchronizers:- None"Service Thread" #9 daemon prio=9 os_prio=31 tid=0x00007ff1d9835000 nid=0x4b03 runnable [0x0000000000000000]java.lang.Thread.State: RUNNABLELocked ownable synchronizers:- None"C1 CompilerThread2" #8 daemon prio=9 os_prio=31 tid=0x00007ff1da87f800 nid=0x4903 waiting on condition [0x0000000000000000]java.lang.Thread.State: RUNNABLELocked ownable synchronizers:- None"C2 CompilerThread1" #7 daemon prio=9 os_prio=31 tid=0x00007ff1d98c5800 nid=0x4703 waiting on condition [0x0000000000000000]java.lang.Thread.State: RUNNABLELocked ownable synchronizers:- None"C2 CompilerThread0" #6 daemon prio=9 os_prio=31 tid=0x00007ff1da886000 nid=0x4503 waiting on condition [0x0000000000000000]java.lang.Thread.State: RUNNABLELocked ownable synchronizers:- None"Monitor Ctrl-Break" #5 daemon prio=5 os_prio=31 tid=0x00007ff1da884800 nid=0x4303 runnable [0x0000700000c3a000]java.lang.Thread.State: RUNNABLEat java.net.SocketInputStream.socketRead0(Native Method)at java.net.SocketInputStream.socketRead(SocketInputStream.java:116)at java.net.SocketInputStream.read(SocketInputStream.java:171)at java.net.SocketInputStream.read(SocketInputStream.java:141)at sun.nio.cs.StreamDecoder.readBytes(StreamDecoder.java:284)at sun.nio.cs.StreamDecoder.implRead(StreamDecoder.java:326)at sun.nio.cs.StreamDecoder.read(StreamDecoder.java:178)- locked <0x00000007958fc840> (a java.io.InputStreamReader)at java.io.InputStreamReader.read(InputStreamReader.java:184)at java.io.BufferedReader.fill(BufferedReader.java:161)at java.io.BufferedReader.readLine(BufferedReader.java:324)- locked <0x00000007958fc840> (a java.io.InputStreamReader)at java.io.BufferedReader.readLine(BufferedReader.java:389)at com.intellij.rt.execution.application.AppMainV2$1.run(AppMainV2.java:64)Locked ownable synchronizers:- None"Signal Dispatcher" #4 daemon prio=9 os_prio=31 tid=0x00007ff1db029800 nid=0x360f runnable [0x0000000000000000]java.lang.Thread.State: RUNNABLELocked ownable synchronizers:- None"Finalizer" #3 daemon prio=8 os_prio=31 tid=0x00007ff1d9820800 nid=0x3003 in Object.wait() [0x000070000092e000]java.lang.Thread.State: WAITING (on object monitor)at java.lang.Object.wait(Native Method)- waiting on <0x0000000795588ec8> (a java.lang.ref.ReferenceQueue$Lock)at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:143)- locked <0x0000000795588ec8> (a java.lang.ref.ReferenceQueue$Lock)at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:164)at java.lang.ref.Finalizer$FinalizerThread.run(Finalizer.java:209)Locked ownable synchronizers:- None"Reference Handler" #2 daemon prio=10 os_prio=31 tid=0x00007ff1d9810800 nid=0x2e03 in Object.wait() [0x000070000082b000]java.lang.Thread.State: WAITING (on object monitor)at java.lang.Object.wait(Native Method)- waiting on <0x0000000795586b68> (a java.lang.ref.Reference$Lock)at java.lang.Object.wait(Object.java:502)at java.lang.ref.Reference.tryHandlePending(Reference.java:191)- locked <0x0000000795586b68> (a java.lang.ref.Reference$Lock)at java.lang.ref.Reference$ReferenceHandler.run(Reference.java:153)Locked ownable synchronizers:- None"VM Thread" os_prio=31 tid=0x00007ff1da026800 nid=0x2c03 runnable "GC task thread#0 (ParallelGC)" os_prio=31 tid=0x00007ff1d9810000 nid=0x2403 runnable "GC task thread#1 (ParallelGC)" os_prio=31 tid=0x00007ff1da00d000 nid=0x2603 runnable "GC task thread#2 (ParallelGC)" os_prio=31 tid=0x00007ff1da00d800 nid=0x2803 runnable "GC task thread#3 (ParallelGC)" os_prio=31 tid=0x00007ff1da00e000 nid=0x2a03 runnable "VM Periodic Task Thread" os_prio=31 tid=0x00007ff1da80d000 nid=0x4d03 waiting on condition JNI global references: 354Found one Java-level deadlock:
=============================
"DieThread_2":waiting to lock monitor 0x00007ff1da80ad58 (object 0x000000079585bee0, a java.lang.Object),which is held by "DieThread_1"
"DieThread_1":waiting to lock monitor 0x00007ff1da808418 (object 0x000000079585bef0, a java.lang.Object),which is held by "DieThread_2"Java stack information for the threads listed above:
===================================================
"DieThread_2":at com.javaagent.thread.DieThread.run(DieThread.java:37)- waiting to lock <0x000000079585bee0> (a java.lang.Object)- locked <0x000000079585bef0> (a java.lang.Object)at java.lang.Thread.run(Thread.java:745)
"DieThread_1":at com.javaagent.thread.DieThread.run(DieThread.java:26)- waiting to lock <0x000000079585bef0> (a java.lang.Object)- locked <0x000000079585bee0> (a java.lang.Object)at java.lang.Thread.run(Thread.java:745)Found 1 deadlock.

通过上面的线程Dump文件信息,我们可以看出来发生了死锁,下面也列出了java级别的锁问题和栈信息:

Found one Java-level deadlock:
=============================
"DieThread_2":waiting to lock monitor 0x00007ff1da80ad58 (object 0x000000079585bee0, a java.lang.Object),which is held by "DieThread_1"
"DieThread_1":waiting to lock monitor 0x00007ff1da808418 (object 0x000000079585bef0, a java.lang.Object),which is held by "DieThread_2"Java stack information for the threads listed above:
===================================================
"DieThread_2":at com.javaagent.thread.DieThread.run(DieThread.java:37)- waiting to lock <0x000000079585bee0> (a java.lang.Object)- locked <0x000000079585bef0> (a java.lang.Object)at java.lang.Thread.run(Thread.java:745)
"DieThread_1":at com.javaagent.thread.DieThread.run(DieThread.java:26)- waiting to lock <0x000000079585bef0> (a java.lang.Object)- locked <0x000000079585bee0> (a java.lang.Object)at java.lang.Thread.run(Thread.java:745)Found 1 deadlock.

并且栈信息中,可以定位到死锁发生的地方。

如果解决死锁,那是因为代码的逻辑存在问题,可以调整代码的逻辑或者业务,来避免死锁。

二、如何避免死锁

  • 避免一个线程同时获取多个锁

  • 避免一个线程在锁内同时占用多个资源,尽量保证每个锁只占用一个资源

  • 尝试使用定时锁,使用 lock.tryLock(timeout) 来替代使用内部锁机制。

  • 对于数据库锁,加锁和解锁必须在一个数据库连接里,否则会出现解锁失败的情况。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/446864.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

C++中lock_guard的学习

lock_guard 锁守卫是一个管理mutex对象的对象&#xff0c;使其始终处于锁定状态。在构造时&#xff0c;mutex对象被调用线程锁定&#xff0c;在销毁时&#xff0c;mutex被解锁。这是最简单的锁&#xff0c;作为一个自动持续时间的对象&#xff0c;它的作用特别大&#xff0c;可…

安卓四大组件简介

安卓四大组件 Activity活动&#xff0c;Service服务&#xff0c;BroadcastRecevicer广播接受器&#xff0c;Content Provider内容提供者 Activity活动 所有程序的流程都运行在activity中 Service服务 只能后台运行&#xff0c;没有界面的长生命周期的代码 BroadcastRece…

WebLogic域的创建与发布

目录一、前言二、准备三、创建域步骤第一步&#xff1a;直接【回车】第二步&#xff1a;直接【回车】第三步&#xff1a;直接【回车】第四步&#xff1a;输入域名称后【回车】第五步&#xff1a;直接【回车】第六步&#xff1a;直接【回车】&#xff08;此步骤是提示域的存放目…

安卓安卓移动操作系统优缺点

安卓移动操作系统优缺点 开发性 丰富的硬件 方便开发 gogle应用 安卓模拟器 手机,手表,电视,车载,安卓cel LogCat的使用–5级(日志) Log.v()–verbose全部信息,黑色 Log.d()–debug调试信息,蓝色 Log.i()–info一般信息,绿色 Log.w()–warning警告信息,橙色 Log.e()–erro…

WebLogic启动失败:java.lang.AssertionError: Could not obtain the localhost address.

目录一、错误信息二、解决方案第一步&#xff1a;查看本机计算机名称第二步&#xff1a;编辑hosts文件一、错误信息 linux下启动WebLogic报如下错误&#xff1a; 二、解决方案 此错误多半是hosts文件不对导致的。 解决步骤如下&#xff1a; 第一步&#xff1a;查看本机计…

sqlite_orm sync_schema源码即翻译

源码 /*** This is a cute function used to replace migration up/down functionality.* It performs check storage schema with actual db schema and:* * if there are excess tables exist in db they are ignored (not dropped)* * every table from storage is comp…

安卓布局UI简介

安卓UI 用户界面UI&#xff08;使用者界面&#xff09; ——系统和用户之间进行交互和信息交换的媒体 由布局和组件组成 软件设计&#xff1a;编码设计和UI设计 布局 ——可定义应用中的界面结构 所有元素都使用View和Viewgroup对象的层次结构进行构建 view微件——构建用户…

Windows查找JDK的路径

第一步&#xff1a;确定是否安装JDK 在控制台输入&#xff1a; java -version输出结果&#xff1a; 此时说明你电脑安装了JDK。 第二步&#xff1a;查找路径 然后在控制台输入&#xff1a; java -verbose输出结果&#xff1a; 从最后的jre目录可以找到相应的jdk目录。 …

boost官方文档同步机制Synchronization mechanisms overview

参考链接 官方文档 Synchronization mechanisms overview Named And Anonymous Synchronization MechanismsTypes Of Synchronization Mechanisms如前所述&#xff0c;如果不能有效地同步对内存的访问&#xff0c;那么通过内存映射文件或共享内存对象在进程之间共享内存的能力…

安卓布局中xml文件属性和ID简介

编写xml属性 加载xml资源 当编译应用时&#xff0c;系统会将每个xml文件编译为view资源 属性 xml属性&#xff1a;特有属性&#xff0c;共有属性&#xff0c;其他属性&#xff08;布局参数&#xff09; ID ——在结构树中对view对象唯一标识 编译应用后&#xff0c;系统以…

Java监控工具VisualVM

目录一、简介二、内存分析1、Heap堆三、CPU分析四、线程分析一、简介 VisualVM 是一款免费的&#xff0c;集成了多个JDK命令行工具的可视化工具&#xff0c;它能为您提供强大的分析能力&#xff0c;对Java应用程序做 性能分析和调优 。这些功能包括 生成和分析海量数据、跟踪内…

对官方Mutexes的翻译

参考链接 参考链接 Mutexes Whats A Mutex?Mutex OperationsBoost.Interprocess Mutex Types And HeadersScoped lockAnonymous mutex exampleNamed mutex example Whats A Mutex? 互斥是相互排斥的意思&#xff0c;它是进程之间最基本的同步形式。互斥保证只有一个线程可…

计算机应用基础

计算概论知识点 1.计算机之父&#xff1a;冯.诺伊曼 计算机基本组成&#xff1a;运算器&#xff0c;控制器&#xff0c;存储器&#xff0c;输入设备&#xff0c;输出设备 2.几种计算机&#xff1a;台式计算机,笔记本式计算机,PC服务器,平板式计算机… 3.电脑的硬件&#xff1a;…

Android最全UI库合集

目录抽屉菜单ListViewWebViewSwitchButton按钮点赞按钮进度条TabLayout图标下拉刷新ViewPager图表(Chart)菜单(Menu)浮动菜单对话框空白页滑动删除手势操作RecyclerViewCardColorDrawableSpinner布局模糊效果TabBarAppBar选择器(Picker)跑马灯日历时间主题样式ImageView通知聊天…

对于boost锁机制结论性的介绍

Conditions Whats A Condition Variable?Boost.Interprocess Condition Types And HeadersAnonymous condition example Whats A Condition Variable? 在前面的例子中&#xff0c;一个mutex被用来锁定&#xff0c;但我们不能用它来有效地等待&#xff0c;直到满足继续的条件…

C++数据类型

C 数据类型 |–基本数据类型: 整型 short短整型 2 int基本整型4 long长整型 8 浮点型 float单精度型 4 double双精度型 8 long double长双精度型 16 字符型 char 1 逻辑型 bool 1 空类型 void |–构造类型 数组类型 构造体类型 struct 共用体类型 union 枚举类型 enum 类类型…

Android Gradle 多渠道打包、动态配置AppName

目录一、简介二、Gradle多渠道打包1、普通做法2、Gradle多渠道打包一、简介 因为国内Android应用分发市场的现状&#xff0c;我们在发布APP时&#xff0c;一般需要生成多个渠道包&#xff0c;上传到不同的应用市场。这些渠道包需要包含不同的渠道信息&#xff0c;在APP和后台交…

boost锁机制中Semaphores的介绍

结构 Whats A Semaphore?Boost.Interprocess Semaphore Types And HeadersAnonymous semaphore example Whats A Semaphore? 旗语是一种基于内部计数的进程间同步机制&#xff0c;它提供了两种基本操作。等待&#xff1a;测试旗语数的值&#xff0c;如果小于或等于0&#x…

Android Gradle 批量修改生成的apk文件名

目录一、简介二、代码实现1、 Gradle 3.0以下版本2、Gradle 3.0以上版本一、简介 平时开发都知道&#xff0c;我们要上线的时候需要在Android studio打包apk文件&#xff0c;可是默认的打包名是app-release.apk或者app-debug.apk这样的名字&#xff0c;太没有辨识度了。 下面…