Java多线程(八)——死锁
来源:互联网 发布:java 圣思园教程百度云 编辑:程序博客网 时间:2024/05/22 14:26
线程A当前持有互斥所锁lock1,线程B当前持有互斥锁lock2。接下来,当线程A仍然持有lock1时,它试图获取lock2,因为线程B正持有lock2,因此线程A会阻塞等待线程B对lock2的释放。如果此时线程B在持有lock2的时候,也在试图获取lock1,因为线程A正持有lock1,因此线程B会阻塞等待A对lock1的释放。二者都在等待对方所持有锁的释放,而二者却又都没释放自己所持有的锁,这时二者便会一直阻塞下去。这种情形称为死锁。
下列代码演示了死锁:
public class ThreadDeadlock { public static void main(String[] args) { Object obj1 = new Object(); Object obj2 = new Object(); Object obj3 = new Object(); Thread t1 = new Thread(new SyncThread(obj1, obj2), "t1"); Thread t2 = new Thread(new SyncThread(obj2, obj3), "t2"); Thread t3 = new Thread(new SyncThread(obj3, obj1), "t3"); try { t1.start(); Thread.sleep(1000); t2.start(); Thread.sleep(1000); t3.start(); } catch (InterruptedException e) { System.out.println("失败!"); } try { Thread.sleep(15000); System.out.println("试图中断死锁的线程t1"); t1.interrupt(); System.out.println("试图中断死锁的线程t2"); t2.interrupt(); System.out.println("试图中断死锁的线程t3"); t3.interrupt(); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } }}class SyncThread implements Runnable { private Object obj1; private Object obj2; public SyncThread(Object o1, Object o2) { this.obj1 = o1; this.obj2 = o2; } @Override public void run() { String name = Thread.currentThread().getName(); System.out.println("线程" + name + " 准备获取" + obj1 + " 的锁 "); synchronized (obj1) { System.out.println("线程" + name + " 已经获取" + obj1 + " 的锁 "); try { Thread.sleep(5000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("线程" + name + " 准备获取" + obj2 + " 的锁 "); synchronized (obj2) { System.out.println("线程" + name + " 已经获取" + obj2 + " 的锁 "); try { Thread.sleep(5000); } catch (InterruptedException e) { e.printStackTrace(); } } } }}
运行结果如下:
线程t1 准备获取java.lang.Object@1102fab 的锁 线程t1 已经获取java.lang.Object@1102fab 的锁 线程t2 准备获取java.lang.Object@16f5b17 的锁 线程t2 已经获取java.lang.Object@16f5b17 的锁 线程t3 准备获取java.lang.Object@b950d1 的锁 线程t3 已经获取java.lang.Object@b950d1 的锁 线程t1 准备获取java.lang.Object@16f5b17 的锁 线程t2 准备获取java.lang.Object@b950d1 的锁 线程t3 准备获取java.lang.Object@1102fab 的锁 试图中断死锁的线程t1试图中断死锁的线程t2试图中断死锁的线程t3
由于t1,t2,t3三个线程分别持有了obj1 ,obj2,obj3的互斥锁。
接下来需要分别获取obj2,obj3,obj1锁,而该锁已分别被t2,t3,t1线程持有。发生死锁现象,调用Thread.interrupt()方法试图中断线程,却发现线程仍然在继续运行。
避免死锁是一件困难的事,遵循以下原则有助于规避死锁:
1、能够原子性的获取需要的多个锁;
2、调整对多个锁的获取顺序;
1 0
- Java多线程(八)——死锁
- Java多线程(6)——死锁
- Java多线程㈢—死锁(示例)
- Java多线程——死锁
- Java多线程(3)——死锁问题
- Java线程和多线程(九)——死锁
- JAVA多线程——死锁分析
- Java多线程初探——死锁
- 多线程——死锁
- 多线程——死锁
- java多线程(5)死锁
- 【Java多线程】多线程死锁
- Java 多线程(八)——实现简单线程池
- Java线程和多线程(八)——Thread Dump
- Java 多线程(八)——实现简单线程池
- Java多线程系列(八)—CyclicBarrier源码分析
- java自学笔记————多线程之死锁;
- java多线程-java死锁
- SurfaceView
- 02-创建一个ROS的WorkSpace目录
- Ubuntu 14.04 移动mysql 数据库
- iOS拨打电话(三种方法)
- Hibernate主从数据库读写分离配置
- Java多线程(八)——死锁
- android 源码编译注意事项
- iOS_缩短app启动时间的一些见解
- 代码编辑器Sublime Text 3使用教程及简体中文汉化包
- 03-创建一个ROS的Package包
- Android开发使用的常见第三方框架汇总
- PopupWindow 定点弹窗使用实例
- ASP.NET MVC IOC 之AutoFac攻略
- 漫谈如何学习操作系统原理