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多线程基本概述(四)——死锁的更多相关文章

  1. “全栈2019”Java多线程第二十四章:等待唤醒机制详解

    难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"Java多 ...

  2. “全栈2019”Java多线程第十四章:线程与堆栈详解

    难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"Java多 ...

  3. Java多线程学习(四)等待/通知(wait/notify)机制

    转载请备注地址:https://blog.csdn.net/qq_34337272/article/details/79690279 系列文章传送门: Java多线程学习(一)Java多线程入门 Ja ...

  4. Java 多线程基础(四)线程安全

    Java 多线程基础(四)线程安全 在多线程环境下,如果有多个线程在同时运行,而这些线程可能会同时运行这段代码.程序每次运行结果和单线程运行的结果是一样的,而且其他的变量的值也和预期的是一样的,就是线 ...

  5. Java多线程编程(同步、死锁、生产消费者问题)

    Java多线程编程(同步.死锁.生产消费): 关于线程同步以及死锁问题: 线程同步概念:是指若干个线程对象并行进行资源的访问时实现的资源处理保护操作: 线程死锁概念:是指两个线程都在等待对方先完成,造 ...

  6. JAVA多线程实现的四种方式

    Java多线程实现方式主要有四种:继承Thread类.实现Runnable接口.实现Callable接口通过FutureTask包装器来创建Thread线程.使用ExecutorService.Cal ...

  7. Java多线程——<一>概述、定义任务

    一.概述 为什么使用线程?从c开始,任何一门高级语言的默认执行顺序是“按照编写的代码的顺序执行”,日常开发过程中写的业务逻辑,但凡不涉及并发的,都是让一个任务顺序执行以确保得到想要的结果.但是,当你的 ...

  8. 【转】JAVA多线程实现的四种方式

    原文地址:http://www.cnblogs.com/felixzh/p/6036074.html Java多线程实现方式主要有四种:继承Thread类.实现Runnable接口.实现Callabl ...

  9. JAVA多线程实现的四种方式(转自https://www.cnblogs.com/felixzh/p/6036074.html)

    Java多线程实现方式主要有四种:继承Thread类.实现Runnable接口.实现Callable接口通过FutureTask包装器来创建Thread线程.使用ExecutorService.Cal ...

随机推荐

  1. loadrunner入门篇-Controller控制器

    Controller组件是LR的控制中心,主要包括场景设计和场景执行两部分.在VuGen中编辑完脚本并将脚本加载到Controller组件中,即开始对脚本运行时的场景进行设计,当场景设计完成后,即可执 ...

  2. ASP.NET MVC 5 基本构成

    MVC模式简介: MVC模式两种理解:一种是表现模式,另外一种是架构模式.它将应用程序分成三个主要组件即:视图(View)控件器(Controller)模型(Model) M: Model主要是存储或 ...

  3. Android: Toolbar、AppBarLayout

    ToolBar是google退出的一个应用程序动作条 包括: 设置导航栏图标 设置应用程序Logo 设置标题 设置子标题 添加各种自定义控件 添加动作条菜单 API:https://developer ...

  4. netflix zuul-simple-webapp.war在tomcat下启动

    按照netflix 在github 的wiki的文档使用 gradlew jettyRun 可以启动jetty来进行测试. 在本地build war 以后,我放在tomcat 运行的时候,却不可以运行 ...

  5. MyBatis快速入门(一)

    一.MyBatis背景介绍 MyBatis是支持普通SQL查询,存储过程和高级映射的优秀持久层框架.MyBatis消除了几乎所有的JDBC代码和参数的手工设置以及结果集的检索.MyBatis使用简单的 ...

  6. pyqt样式表语法笔记

    pyqt样式表语法笔记 pyqt QSS python 样式表 因为软件课设的原因开始学习使用pyqt4,才发现原来它也有样式表,而且语法跟css基本相同,而且一些功能实现起来感觉比js要简单方便得多 ...

  7. The 15th UESTC Programming Contest Preliminary G - GC?(X,Y) cdoj1564

    地址:http://acm.uestc.edu.cn/#/problem/show/1564 题目: G - GC?(X,Y) Time Limit: 3000/1000MS (Java/Others ...

  8. 在线上服务器上无管理员权限下升级NodeJS版本

    前言 最近发现一个线上机器的问题,是因为node版本过低导致的,线上机器的node版本还是0.x版,遂打算升级node版本. 但是发现常规的npm包的n模块无法使用,提示没有权限创建文件夹,导致nod ...

  9. 【Java 并发】详解 ThreadLocal

    前言 ThreadLocal 主要用来提供线程局部变量,也就是变量只对当前线程可见,本文主要记录一下对于 ThreadLocal 的理解.更多关于 Java 多线程的文章可以转到 这里. 线程局部变量 ...

  10. Openstack新建云主机的流程

    前言 前天晚上没睡觉,所以昨天睡得很早,导致今天4点就起来了 时间是人最宝贵的财富,于是我打消了钻在被子里刷剧的念头,爬起来整理一下在Openstack中新建一个云主机的流程. Openstack可以 ...