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. PCB行业ERP解决方案

    普实PCB管理系统包括PCB企业从接到订单开始,编排生产计划.制作工程指示.生产工具.准备物料.品质保障.工序生产.设备维护等一系列与企业运作密切相关的环节,使得企业的各个部门能够紧密联系.相互协调, ...

  2. Robot Framework中经常用的第三方库的安装方法

    pip升级:python -m pip install --upgrade pip 一.安装robotframework-selenium2library,相当于python中的selenium    ...

  3. 如何让celery接受定制的参数

    背景介绍 最近的一个项目使用到celery结算订单,使用celery的确很方便.但是复杂的内部框架导致了需要传人大量的参数例如数据库配置文件等.下面先来看看我仿照官网写的代码.所有代码都放到githu ...

  4. 【Unity编程】欧拉角与万向节死锁(图文版)

    版权声明:本文为博主原创文章,欢迎转载.请保留博主链接:http://blog.csdn.net/andrewfan 万向节死锁(Gimbal Lock)问题 上文中曾经说过,欧拉旋转的顺规和轴向定义 ...

  5. 浅谈Java的集合框架

    浅谈Java的集合框架 一.    初识集合 重所周知,Java有四大集合框架群,Set.List.Queue和Map.四种集合的关注点不同,Set 关注事物的唯一性,List 关注事物的索引列表,Q ...

  6. a中的类型转换

    自动类型转换 当然自动类型转换是需要满足特定的条件的: 1.  目标类型能与源类型兼容,如 double 型兼容 int 型,但是 char 型不能兼容 int 型. 2.  目标类型大于源类型,如 ...

  7. mysql 修改数据库data存放位置

    一.首先把mysql的服务先停掉. 二.更改MySQL配置文件My.ini中的数据库存储主路径 打开MySQL默认的安装文件夹C:\Program Files\MySQL\MySQL Server 5 ...

  8. HTML+CSS-采用DIV+CSS布局的利弊

    单纯的TABLE表格,在浏览器运行上面来说,其效率不如DIV+CSS方式快速,当然,这样也就会影响用的体验. 而且,针对于相同的HTML页面来说TABLE布局,不利于搜索引擎的爬虫爬行下载页面.从而造 ...

  9. php数组的使用

    <?php echo "<h2>--------普通数组--------</h2>"; $arr1 = array(1,2,3,4); print_r ...

  10. [译]Selenium Python文档:七、WebDriver API接口

    由于API文档格式不太适合cnblog博客,暂且翻译一部分,且暂未校对 注意:这不是官方文档,官方 API文档在这里. 本章包含Selenium WebDriver的所有接口 推荐import风格 本 ...