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

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

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. Selenium2Library系列 keywords 之 _SelectElementKeywords 之 select_from_list_by_value(self, locator, *values)

    def select_from_list_by_value(self, locator, *values): """Selects `*values` from list ...

  2. 转-sketch技巧

    10个帮你UI设计提速的Sketch使用技巧 2015-4-11 09:59| 发布者: yuanxingbbs| 查看: 1129| 评论: 0   选择使用Sketch的理由很多,因为好奇跟风安装 ...

  3. 使用VMware10虚拟机安装Linux系统(能力工场)

    作为IT从业人员,我们经常使用到Linux系统,但是实际开发过程我们通常在Windows平台操作,为了满足工作需要,这个时候我们通常在windows平台安装虚拟机,并在其上建立linux系统,这样就极 ...

  4. Bubble Sort

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8&quo ...

  5. 怎么监视跟踪一个进程(Process)中的MS Unit Test DLL的详细性能(performance)【asp.net C#】

    Sample This tutorial will show how to instrument a unit test DLL for performance profiling. Visual S ...

  6. CSRF简单介绍及利用方法-跨站请求伪造

    0x00 简要介绍 CSRF(Cross-site request forgery)跨站请求伪造,由于目标站无token/referer限制,导致攻击者可以用户的身份完成操作达到各种目的.根据HTTP ...

  7. reds pub/sub官方文档翻译

    Publish / Subscribe发布/订阅 redis-py includes a PubSub object that subscribes to channels and listens f ...

  8. ef6 code first

    http://www.cnblogs.com/Bce-/p/3684643.html http://www.cnblogs.com/Gyoung/tag/Entity%20Framework/ htt ...

  9. java Study 基础 1

    1.myEclipse 生成get.set,source>Generate getter and setter 2.Web servlet.HttpServlet.HttpServletRequ ...

  10. 一个效果很华丽的仿桌面APP,却胜似Launcher

    开发Android APP的同学是否对于Launcher实现的绚丽效果而痴迷呢?什么,连Android Launcher是什么都不知道.好吧,拿起侬的手机,在解锁后的首页界面上左右滑动滑动,体验体验, ...