java多线程基本概述(四)——死锁
package mytask; public class Task {
public static void main(String[] args) {
DeadThread thread = new DeadThread();
Thread t1 = new Thread(thread);
t1.setName("a");
Thread t2 = new Thread(thread);
t2.setName("b");
t1.start();
t2.start();
}
} class DeadThread implements Runnable{
private String o1= new String("o1");
private String o2 = new String("o2");
@Override
public void run() {
if(Thread.currentThread().getName().equals("a")){
synchronized(o1){
System.out.println("a thread enter outer monitor o1....");
try{
Thread.sleep(3000);
System.out.println("a waiting for o2 monitor...");
synchronized(o2){
System.out.println("a thread enter inner monitr o2");
}
}catch(InterruptedException e){
e.printStackTrace();
}
}
}else{
synchronized(o2){
System.out.println("b thread enter outer monitor o1....");
try{
Thread.sleep(3000);
System.out.println("b waiting for o1 monitor...");
synchronized(o1){
System.out.println("b thread enter inner monitr o1");
}
}catch(InterruptedException e){
e.printStackTrace();
}
}
}
} }
输出结果:
a thread enter outer monitor o1....
b thread enter outer monitor o1....
a waiting for o2 monitor...
b waiting for o1 monitor...
一致处于阻塞状态,可以通过jps命令查看信息得到
8064 Task
3832
3388 Jps
然后再执行 jstack -l 8064
得到信息
Full thread dump Java HotSpot(TM) 64-Bit Server VM (20.6-b01 mixed mode): "DestroyJavaVM" prio=6 tid=0x000000000096c000 nid=0x494 waiting on condition [0x0000000000000000]
java.lang.Thread.State: RUNNABLE Locked ownable synchronizers:
- None "b" prio=6 tid=0x0000000006d66800 nid=0x548 waiting for monitor entry [0x000000000772f000]
java.lang.Thread.State: BLOCKED (on object monitor)
at mytask.DeadThread.run(Task.java:40)
- waiting to lock <0x00000007c099b648> (a java.lang.String)
- locked <0x00000007c099b668> (a java.lang.String)
at java.lang.Thread.run(Thread.java:662) Locked ownable synchronizers:
- None "a" prio=6 tid=0x0000000006d66000 nid=0x1354 waiting for monitor entry [0x000000000762f000]
java.lang.Thread.State: BLOCKED (on object monitor)
at mytask.DeadThread.run(Task.java:27)
- waiting to lock <0x00000007c099b668> (a java.lang.String)
- locked <0x00000007c099b648> (a java.lang.String)
at java.lang.Thread.run(Thread.java:662) Locked ownable synchronizers:
- None "Low Memory Detector" daemon prio=6 tid=0x00000000025bf000 nid=0x1890 runnable [0x0000000000000000]
java.lang.Thread.State: RUNNABLE Locked ownable synchronizers:
- None "C2 CompilerThread1" daemon prio=10 tid=0x00000000025b5800 nid=0x1bb8 waiting on condition [0x0000000000000000]
java.lang.Thread.State: RUNNABLE Locked ownable synchronizers:
- None "C2 CompilerThread0" daemon prio=10 tid=0x00000000025ac800 nid=0x1ee8 waiting on condition [0x0000000000000000]
java.lang.Thread.State: RUNNABLE Locked ownable synchronizers:
- None "Attach Listener" daemon prio=10 tid=0x00000000025ab800 nid=0x480 waiting on condition [0x0000000000000000]
java.lang.Thread.State: RUNNABLE Locked ownable synchronizers:
- None "Signal Dispatcher" daemon prio=10 tid=0x00000000025a8800 nid=0xebc runnable [0x0000000000000000]
java.lang.Thread.State: RUNNABLE Locked ownable synchronizers:
- None "Finalizer" daemon prio=8 tid=0x0000000002592000 nid=0x1dd0 in Object.wait() [0x0000000006d2f000]
java.lang.Thread.State: WAITING (on object monitor)
at java.lang.Object.wait(Native Method)
- waiting on <0x00000007c0961300> (a java.lang.ref.ReferenceQueue$Lock)
at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:118)
- locked <0x00000007c0961300> (a java.lang.ref.ReferenceQueue$Lock)
at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:134)
at java.lang.ref.Finalizer$FinalizerThread.run(Finalizer.java:159) Locked ownable synchronizers:
- None "Reference Handler" daemon prio=10 tid=0x000000000258e800 nid=0x1560 in Object.wait() [0x0000000006c2f000]
java.lang.Thread.State: WAITING (on object monitor)
at java.lang.Object.wait(Native Method)
- waiting on <0x00000007c09611d8> (a java.lang.ref.Reference$Lock)
at java.lang.Object.wait(Object.java:485)
at java.lang.ref.Reference$ReferenceHandler.run(Reference.java:116)
- locked <0x00000007c09611d8> (a java.lang.ref.Reference$Lock) Locked ownable synchronizers:
- None "VM Thread" prio=10 tid=0x0000000002588000 nid=0x1d38 runnable "GC task thread#0 (ParallelGC)" prio=6 tid=0x00000000024e1800 nid=0x1e40 runnable "GC task thread#1 (ParallelGC)" prio=6 tid=0x00000000024e3000 nid=0x1854 runnable "GC task thread#2 (ParallelGC)" prio=6 tid=0x00000000024e4800 nid=0x1e00 runnable "GC task thread#3 (ParallelGC)" prio=6 tid=0x00000000024e6800 nid=0x970 runnable "VM Periodic Task Thread" prio=10 tid=0x00000000025c2000 nid=0xf00 waiting on condition JNI global references: 882 Found one Java-level deadlock:
=============================
"b":
waiting to lock monitor 0x0000000002598548 (object 0x00000007c099b648, a java.lang.String),
which is held by "a"
"a":
waiting to lock monitor 0x0000000002595de8 (object 0x00000007c099b668, a java.lang.String),
which is held by "b" Java stack information for the threads listed above:
===================================================
"b":
at mytask.DeadThread.run(Task.java:40)
- waiting to lock <0x00000007c099b648> (a java.lang.String)
- locked <0x00000007c099b668> (a java.lang.String)
at java.lang.Thread.run(Thread.java:662)
"a":
at mytask.DeadThread.run(Task.java:27)
- waiting to lock <0x00000007c099b668> (a java.lang.String)
- locked <0x00000007c099b648> (a java.lang.String)
at java.lang.Thread.run(Thread.java:662) Found 1 deadlock.
死锁的一个经典场景为哲学家就餐问题。 产生死锁的原因主要是:
(1) 因为系统资源不足。
(2) 进程运行推进的顺序不合适。
(3) 资源分配不当等。
如果系统资源充足,进程的资源请求都能够得到满足,死锁出现的可能性就很低,否则就会因争夺有限的资源而陷入死锁。其次,进程运行推进顺序与速度不同,也可能产生死锁。
产生死锁的四个必要条件:
(1) 互斥条件:一个资源每次只能被一个进程使用。
(2) 请求与保持条件:一个进程因请求资源而阻塞时,对已获得的资源保持不放。
(3) 不剥夺条件:进程已获得的资源,在末使用完之前,不能强行剥夺。
(4) 循环等待条件:若干进程之间形成一种头尾相接的循环等待资源关系。
这四个条件是死锁的必要条件,只要系统发生死锁,这些条件必然成立,而只要上述条件之一不满足,就不会发生死锁。
死锁的解除与预防:
理解了死锁的原因,尤其是产生死锁的四个必要条件,就可以最大可能地避免、预防和
解除死锁。所以,在系统设计、进程调度等方面注意如何不让这四个必要条件成立,如何确
定资源的合理分配算法,避免进程永久占据系统资源。此外,也要防止进程在处于等待状态
的情况下占用资源。因此,对资源的分配要给予合理的规划。
java多线程基本概述(四)——死锁的更多相关文章
- “全栈2019”Java多线程第二十四章:等待唤醒机制详解
难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"Java多 ...
- “全栈2019”Java多线程第十四章:线程与堆栈详解
难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"Java多 ...
- Java多线程学习(四)等待/通知(wait/notify)机制
转载请备注地址:https://blog.csdn.net/qq_34337272/article/details/79690279 系列文章传送门: Java多线程学习(一)Java多线程入门 Ja ...
- Java 多线程基础(四)线程安全
Java 多线程基础(四)线程安全 在多线程环境下,如果有多个线程在同时运行,而这些线程可能会同时运行这段代码.程序每次运行结果和单线程运行的结果是一样的,而且其他的变量的值也和预期的是一样的,就是线 ...
- Java多线程编程(同步、死锁、生产消费者问题)
Java多线程编程(同步.死锁.生产消费): 关于线程同步以及死锁问题: 线程同步概念:是指若干个线程对象并行进行资源的访问时实现的资源处理保护操作: 线程死锁概念:是指两个线程都在等待对方先完成,造 ...
- JAVA多线程实现的四种方式
Java多线程实现方式主要有四种:继承Thread类.实现Runnable接口.实现Callable接口通过FutureTask包装器来创建Thread线程.使用ExecutorService.Cal ...
- Java多线程——<一>概述、定义任务
一.概述 为什么使用线程?从c开始,任何一门高级语言的默认执行顺序是“按照编写的代码的顺序执行”,日常开发过程中写的业务逻辑,但凡不涉及并发的,都是让一个任务顺序执行以确保得到想要的结果.但是,当你的 ...
- 【转】JAVA多线程实现的四种方式
原文地址:http://www.cnblogs.com/felixzh/p/6036074.html Java多线程实现方式主要有四种:继承Thread类.实现Runnable接口.实现Callabl ...
- JAVA多线程实现的四种方式(转自https://www.cnblogs.com/felixzh/p/6036074.html)
Java多线程实现方式主要有四种:继承Thread类.实现Runnable接口.实现Callable接口通过FutureTask包装器来创建Thread线程.使用ExecutorService.Cal ...
随机推荐
- linux中添加环境变量(python为例)
最近想用Django搭建个人博客,之前学了些python基础语法,准备边学习Django边实战操作.自己有一个阿里云服务器,用的centOS,自带的是python2.7版本,我直接安装了python3 ...
- Java I/O之NIO Socket
PS:本文简单介绍下旧I/O和NIO下的Socket通讯,仅以UDP来示例. TCP/IP协议 首先简单回顾下TCP/IP协议 Application:应用程序:Socket:套接字:Host:主机: ...
- maven新建的项目,不自动引入依赖包
1.检查repository的目录是不是纯英文. 2.重新下载一次repository. 如果解决了问题,那么原因就是前面在加载repository的时候,因为断网导致了下载的包有误,无法被ecl ...
- 1702: [Usaco2007 Mar]Gold Balanced Lineup 平衡的队列
1702: [Usaco2007 Mar]Gold Balanced Lineup 平衡的队列 Time Limit: 5 Sec Memory Limit: 64 MBSubmit: 510 S ...
- 1270: [BeijingWc2008]雷涛的小猫
1270: [BeijingWc2008]雷涛的小猫 Time Limit: 50 Sec Memory Limit: 162 MBSubmit: 905 Solved: 430[Submit][ ...
- 轻松理解JavaScript闭包
摘要 闭包机制是JavaScript的重点和难点,本文希望能帮助大家轻松的学习闭包 一.什么是闭包? 闭包就是可以访问另一个函数作用域中变量的函数. 下面列举出常见的闭包实现方式,以例子讲解闭包概念 ...
- TypeScript设计模式之中介者、观察者
看看用TypeScript怎样实现常见的设计模式,顺便复习一下. 学模式最重要的不是记UML,而是知道什么模式可以解决什么样的问题,在做项目时碰到问题可以想到用哪个模式可以解决,UML忘了可以查,思想 ...
- 腾讯云数据库团队:phpMyAdmin中sql-parser组件的使用
phpMyAdmin是一款基于Web端运行的开源数据库管理工具,支持管理MySQL和MariaDB两种数据库. phpMyAdmin的程序主要使用php和javascript开发,它的安装使用都比较简 ...
- C# 使用 USB转串 接收数据 问题
C# 使用 USB转串 接收数据的 问题 硬件设备是MicroUSB接口,通过USB转串驱动接入PC机.自己用winForm写了一个读取串口数据的小程序,总是接收不到数据. 用传sscom32串口工具 ...
- 2017年你需要一个VPN
还有29天就2017年了,今天跟同事还在讨论这个问题,2016你都做了些什么事情?2017你有什么计划和期待?有空我们一起来聊聊,今天我们就先来聊聊VPN. 记得2016年11月初的时候,我写过一篇文 ...