发生死锁的原因通常是两个对象的锁相互等待造成的。

以下用一个实例来构造这样的情况:

package basic.e_deadlock;

import org.apache.log4j.Logger;

public class TestDeadLock {
public static void main(String[] args) {
DeadlockRisk dead = new DeadlockRisk();
MyThread t1 = new MyThread(dead, 1, 2, "线程1");
MyThread t2 = new MyThread(dead, 3, 4, "线程2");
MyThread t3 = new MyThread(dead, 5, 6, "线程3");
MyThread t4 = new MyThread(dead, 7, 8, "线程4");
t1.start();
t2.start();
t3.start();
t4.start();
}
} class MyThread extends Thread {
private DeadlockRisk dead;
private int a, b; MyThread(DeadlockRisk dead, int a, int b, String threadName) {
this.dead = dead;
this.a = a;
this.b = b;
this.setName(threadName);
} @Override
public void run() {
dead.read();
dead.write(a, b);
}
} class DeadlockRisk {
private static Logger logger = Logger.getLogger(DeadlockRisk.class);
private static class Resource {
public int value;
} private Resource resourceA = new Resource();
private Resource resourceB = new Resource(); public void read() {
logger.debug("===========read begin===========");
synchronized (resourceA) {
logger.debug("read():" + Thread.currentThread().getName() + "获取了resourceA 的锁!");
synchronized (resourceB) {
logger.debug("read():" + Thread.currentThread().getName() + "获取了resourceB 的锁!");
}
}
logger.debug("===========read end=============");
} public void write(int a, int b) {
logger.debug("===========write begin===========");
synchronized (resourceB) {
logger.debug("write():" + Thread.currentThread().getName() + "获取了resourceB 的锁!");
synchronized (resourceA) {
logger.debug("write():" + Thread.currentThread().getName() + "获取了resourceA 的锁!");
resourceA.value = a;
resourceB.value = b;
}
}
logger.debug("===========write end=============");
}
}

运行结果:

0    [线程1] DEBUG basic.e_deadlock.DeadlockRisk - ===========read  begin===========
0 [线程2] DEBUG basic.e_deadlock.DeadlockRisk - ===========read begin===========
0 [线程4] DEBUG basic.e_deadlock.DeadlockRisk - ===========read begin===========
0 [线程3] DEBUG basic.e_deadlock.DeadlockRisk - ===========read begin===========
0 [线程1] DEBUG basic.e_deadlock.DeadlockRisk - read():线程1获取了resourceA 的锁!
0 [线程1] DEBUG basic.e_deadlock.DeadlockRisk - read():线程1获取了resourceB 的锁!
0 [线程1] DEBUG basic.e_deadlock.DeadlockRisk - ===========read end=============
0 [线程2] DEBUG basic.e_deadlock.DeadlockRisk - read():线程2获取了resourceA 的锁!
0 [线程1] DEBUG basic.e_deadlock.DeadlockRisk - ===========write being===========
1 [线程2] DEBUG basic.e_deadlock.DeadlockRisk - read():线程2获取了resourceB 的锁!
1 [线程2] DEBUG basic.e_deadlock.DeadlockRisk - ===========read end=============
1 [线程2] DEBUG basic.e_deadlock.DeadlockRisk - ===========write being===========
1 [线程1] DEBUG basic.e_deadlock.DeadlockRisk - write():线程1获取了resourceB 的锁!
1 [线程4] DEBUG basic.e_deadlock.DeadlockRisk - read():线程4获取了resourceA 的锁!

注意:此时线程1在等待resourceB的资源,线程2在等待resourceA的资源。两个线程在相互等待,出现死锁。

Java多线程:线程死锁的更多相关文章

  1. Java多线程——线程的死锁

    Java多线程——线程的死锁 摘要:本文主要介绍了Java多线程中遇到的死锁问题. 部分内容来自以下博客: https://www.cnblogs.com/wy697495/p/9757982.htm ...

  2. java 多线程—— 线程让步

    java 多线程 目录: Java 多线程——基础知识 Java 多线程 —— synchronized关键字 java 多线程——一个定时调度的例子 java 多线程——quartz 定时调度的例子 ...

  3. java 多线程—— 线程等待与唤醒

    java 多线程 目录: Java 多线程——基础知识 Java 多线程 —— synchronized关键字 java 多线程——一个定时调度的例子 java 多线程——quartz 定时调度的例子 ...

  4. Java多线程--线程及相关的Java API

    Java多线程--线程及相关的Java API 线程与进程 进程是线程的容器,程序是指令.数据的组织形式,进程是程序的实体. 一个进程中可以容纳若干个线程,线程是轻量级的进程,是程序执行的最小单位.我 ...

  5. Java多线程-线程的同步(同步方法)

    线程的同步是保证多线程安全访问竞争资源的一种手段.线程的同步是Java多线程编程的难点,往往开发者搞不清楚什么是竞争资源.什么时候需要考虑同步,怎么同步等等问题,当然,这些问题没有很明确的答案,但有些 ...

  6. Java多线程——线程的优先级和生命周期

    Java多线程——线程的优先级和生命周期 摘要:本文主要介绍了线程的优先级以及线程有哪些生命周期. 部分内容来自以下博客: https://www.cnblogs.com/sunddenly/p/41 ...

  7. Java多线程——线程的创建方式

    Java多线程——线程的创建方式 摘要:本文主要学习了线程的创建方式,线程的常用属性和方法,以及线程的几个基本状态. 部分内容来自以下博客: https://www.cnblogs.com/dolph ...

  8. Java多线程——线程之间的协作

    Java多线程——线程之间的协作 摘要:本文主要学习多线程之间是如何协作的,以及如何使用wait()方法与notify()/notifyAll()方法. 部分内容来自以下博客: https://www ...

  9. Java多线程——线程之间的同步

    Java多线程——线程之间的同步 摘要:本文主要学习多线程之间是如何同步的,如何使用volatile关键字,如何使用synchronized修饰的同步代码块和同步方法解决线程安全问题. 部分内容来自以 ...

随机推荐

  1. DuiLib消息处理剖析

    本来想自己写写duilib的消息机制来帮助duilib的新手朋友,不过今天发现已经有人写过了,而且写得很不错,把duilib的主干消息机制都说明了,我就直接转载过来了,原地址:http://blog. ...

  2. Downloading the Source

    The Android source tree is located in a Git repository hosted by Google. This document  describes ho ...

  3. Jcrop+strut2+jsp实现图片剪切

    在网上找,发现都是不全的,要么没获取图片路径,要么没后台等等,今天就来个全的 一:总体步骤 =>页面上传图片 =>获取上传图片剪切的四个值x,y,w,h =>后天进行剪切 接下来就开 ...

  4. [转载]我读过最好的Epoll模型讲解

    转载来自:http://blog.csdn.net/mango_song/article/details/42643971 首先我们来定义流的概念,一个流可以是文件,socket,pipe等等可以进行 ...

  5. Firefox 对条件判断语句块内的函数声明的处理与其他浏览器有差异

    标准参考 函数声明和函数表达式 定义一个函数有两种途径:函数声明和函数表达式. 函数声明: function Identifier ( FormalParameterList opt ) { Func ...

  6. Mapreduce读取Hbase表,写数据到多个Hbase表中

    Job端的变化: 通过设置conf,配置输出表,在reduce中获取输出表名字 Configuration conf = job.getConfiguration(); //输出表1 conf.set ...

  7. SSO单点登录在web上的关键点 cookie跨域

    概述 其实WEB单点登录的原理挺简单的,抛开那些复杂的概念,简单来讲讲如何实现一个最基本的单点登录 首先需要有两个程序 例如:http://www.site-a.com 我们简称A http://ww ...

  8. POJ 2395 Out of Hay(MST)

    [题目链接]http://poj.org/problem?id=2395 [解题思路]找最小生成树中权值最大的那条边输出,模板过的,出现了几个问题,开的数据不够大导致运行错误,第一次用模板,理解得不够 ...

  9. jQuery和js如何判断checkbox是否选中

    jquery: <div id="divId" class="divTable"><div class="tableBody&quo ...

  10. HDU 5705 Clock (精度控制,暴力)

    题意:给定一个开始时间和一个角度,问你下一个时刻时针和分针形成这个角度是几点. 析:反正数量很小,就可以考虑暴力了,从第一秒开始暴力,直到那个角度即可,不会超时的,数目很少,不过要注意精度. 代码如下 ...