`

使用资源排序解决Java线程死锁解决的方法

阅读更多

      经常看以前大学里面的教材中的一个解决线程死锁的例子,其技术叫做"资源排序",但代码只是一部分,我今天把它写全,这里的关键点是线程对各个对象加锁顺序一定得保持一致.

 

/**
 * 此类轻易的解决了死锁问题,其核心思想为 各线程按照顺序依次对各对象加锁,
 * 假设有三个线程需要竞争三个资源,线程加锁顺序是 lock1,lock2,lock3,这个应该称作为 "资源排序"
 * 
 * @author Chase
 *
 */
public class DeadLockSolution {
	private static final Object lock1 = new Object();

	private static final Object lock2 = new Object();
	
	private static final Object lock3 = new Object();

	private Thread1 thread1 = new Thread1();

	private Thread2 thread2 = new Thread2();
	
	private Thread3 thread3 = new Thread3();

	class Thread1 extends Thread {
		public void run() {
			synchronized (lock1) {
				
				System.out.println("线程1已对 1资源 加锁");
				
				try {
					
					Thread.sleep(1000);
					
				} catch (InterruptedException e) {}
				
				
				synchronized (lock2) {
					
					System.out.println("线程1已对 2资源 加锁");
					
					try {
						
						Thread.sleep(1000);
						
					} catch (InterruptedException e) {}
					
					synchronized (lock3) {
						
						System.out.println("线程1已对 3资源 加锁");
						
						try {
							
							Thread.sleep(1000);
							
						} catch (InterruptedException e) {}
					}
				}
			}
			System.out.println("线程1运行完毕!");
		}
	}

	class Thread2 extends Thread {
		public void run() {
			
			synchronized (lock1) {
				
				System.out.println("线程2已对 1资源 加锁");
				
				try {
					
					Thread.sleep(1000);
					
				} catch (InterruptedException e) {}
				
				synchronized (lock2) {
					
					System.out.println("线程2已对 2资源 加锁");
					
					try {
						
						Thread.sleep(1000);
						
					} catch (InterruptedException e) {}
					
					synchronized (lock3) {
						
						System.out.println("线程2已对 3资源 加锁");
						
						try {
							
							Thread.sleep(1000);
							
						} catch (InterruptedException e) {}
					}
				}
			}
			System.out.println("线程2运行完毕!");
		}
	}
	
	class Thread3 extends Thread {
		public void run() {
			
			synchronized (lock1) {
				
				System.out.println("线程3已对 1资源 加锁");
				
				try {
					
					Thread.sleep(1000);
					
				} catch (InterruptedException e) {}
				
				synchronized (lock2) {
					
					System.out.println("线程3已对 2资源 加锁");
					
					try {
						
						Thread.sleep(1000);
						
					} catch (InterruptedException e) {}
					
					synchronized (lock3) {
						
						System.out.println("线程3已对 3资源 加锁");
						
						try {
							
							Thread.sleep(1000);
							
						} catch (InterruptedException e) {}
					}
				}
			}
			System.out.println("线程3运行完毕!");
		}
	}

	public DeadLockSolution() {
		thread1.start();
		thread2.start();
		thread3.start();
	}

	public static void main(String[] args) {
		new DeadLockSolution();
	}
}

 

运行结果:

 

线程1已对 1资源 加锁
线程1已对 2资源 加锁
线程1已对 3资源 加锁
线程1运行完毕!
线程3已对 1资源 加锁
线程3已对 2资源 加锁
线程3已对 3资源 加锁
线程2已对 1资源 加锁
线程3运行完毕!
线程2已对 2资源 加锁
线程2已对 3资源 加锁
线程2运行完毕! 

 

不同的机器线程运行的先后可能不太一样,但是应该不会出现死锁的情况.

3
7
分享到:
评论

相关推荐

    java应用程序中使用线程

    3.1 Java线程 3.2 创建线程 3.3 使用线程的缺点 3.3.1 初始启动变慢 3.3.2 资源利用 3.3.2 资源利用 3.4 线程管理 3.5 共享资源的使用同步 3.5.1 同步方法和同步代码块的嵌套调用...

    java多线程安全性基础介绍.pptx

    java多线程安全性基础介绍 线程安全 正确性 什么是线程安全性 原子性 竞态条件 i++ 读i ++ 值写回i 可见性 JMM 由于cpu和内存加载速度的差距,在两者之间增加了多级缓存导致,内存并不能直接对cpu可见。 ...

    Java资源包01

    JCarder 是一个用来查找多线程应用程序中一些潜在的死锁,通过对 Java 字节码的动态分析来完成死锁分析。 Java的Flash解析、生成器 jActionScript jActionScript 是一个使用了 JavaSWF2 的 Flash 解析器和生成器。...

    JAVA 范例大全 光盘 资源

    JAVA 范例大全 光盘 资源 书籍目录: 前言. 第1章 开发环境搭建 1 实例1 下载、安装并配置JDK 1 实例2 第一个Java程序 3 实例3 在Eclipse中创建第一个Java程序 4 常见问题 javac不是内部或者外部命令 6 常见...

    java 编程入门思考

    3.1 使用Java运算符 3.1.1 优先级 3.1.2 赋值 3.1.3 算术运算符 3.1.4 自动递增和递减 3.1.5 关系运算符 3.1.6 逻辑运算符 3.1.7 按位运算符 3.1.8 移位运算符 3.1.9 三元if-else运算符 3.1.10 逗号运算符 3.1.11 ...

    疯狂JAVA讲义

    学生提问:当我们使用编译C程序时,不仅需要指定存放目标文件的位置,也需要指定目标文件的文件名,这里使用javac编译Java程序时怎么不需要指定目标文件的文件名呢? 13 1.5.3 运行Java程序 14 1.5.4 根据...

    java开源包8

    JCarder 是一个用来查找多线程应用程序中一些潜在的死锁,通过对 Java 字节码的动态分析来完成死锁分析。 Java的Flash解析、生成器 jActionScript jActionScript 是一个使用了 JavaSWF2 的 Flash 解析器和生成器。...

    Java初学者入门教学

    3.1 使用Java运算符 3.1.1 优先级 3.1.2 赋值 3.1.3 算术运算符 3.1.4 自动递增和递减 3.1.5 关系运算符 3.1.6 逻辑运算符 3.1.7 按位运算符 3.1.8 移位运算符 3.1.9 三元if-else运算符 3.1.10 逗号运算符 3.1.11 ...

    java联想(中文)

    3.1 使用Java运算符 3.1.1 优先级 3.1.2 赋值 3.1.3 算术运算符 3.1.4 自动递增和递减 3.1.5 关系运算符 3.1.6 逻辑运算符 3.1.7 按位运算符 3.1.8 移位运算符 3.1.9 三元if-else运算符 3.1.10 逗号运算符 3.1.11 ...

    JAVA上百实例源码以及开源项目

     Java编写的HTML浏览器源代码,一个很简单甚至不算是浏览器的HTML浏览器,使用方法:  可直接输入文件名或网络地址,但必需事先连入网络。 Java编写的山寨QQ,多人聊天+用户在线 21个目标文件 摘要:JAVA源码,...

    JAVA上百实例源码以及开源项目源代码

     Java编写的HTML浏览器源代码,一个很简单甚至不算是浏览器的HTML浏览器,使用方法:  可直接输入文件名或网络地址,但必需事先连入网络。 Java编写的山寨QQ,多人聊天+用户在线 21个目标文件 摘要:JAVA源码,...

    java jdk实列宝典 光盘源代码

    java为数据结构中的列表定义了一个接口类java.util.list同时提供了3个实现类,分别是ArrayList、Vector、LinkedList使用; 生成不重复的随机数序列;列表、集合与数组的互相转换;java为数据结构中的映射定义一个接口...

    JAVA_Thinking in Java

    3.1 使用Java运算符 3.1.1 优先级 3.1.2 赋值 3.1.3 算术运算符 3.1.4 自动递增和递减 3.1.5 关系运算符 3.1.6 逻辑运算符 3.1.7 按位运算符 3.1.8 移位运算符 3.1.9 三元if-else运算符 3.1.10 逗号运算符 3.1.11 ...

    java开源包11

    JCarder 是一个用来查找多线程应用程序中一些潜在的死锁,通过对 Java 字节码的动态分析来完成死锁分析。 Java的Flash解析、生成器 jActionScript jActionScript 是一个使用了 JavaSWF2 的 Flash 解析器和生成器。...

    java开源包6

    JCarder 是一个用来查找多线程应用程序中一些潜在的死锁,通过对 Java 字节码的动态分析来完成死锁分析。 Java的Flash解析、生成器 jActionScript jActionScript 是一个使用了 JavaSWF2 的 Flash 解析器和生成器。...

    java开源包4

    JCarder 是一个用来查找多线程应用程序中一些潜在的死锁,通过对 Java 字节码的动态分析来完成死锁分析。 Java的Flash解析、生成器 jActionScript jActionScript 是一个使用了 JavaSWF2 的 Flash 解析器和生成器。...

    java开源包9

    JCarder 是一个用来查找多线程应用程序中一些潜在的死锁,通过对 Java 字节码的动态分析来完成死锁分析。 Java的Flash解析、生成器 jActionScript jActionScript 是一个使用了 JavaSWF2 的 Flash 解析器和生成器。...

    java开源包101

    JCarder 是一个用来查找多线程应用程序中一些潜在的死锁,通过对 Java 字节码的动态分析来完成死锁分析。 Java的Flash解析、生成器 jActionScript jActionScript 是一个使用了 JavaSWF2 的 Flash 解析器和生成器。...

    Thinking in Java简体中文(全)

    3.1 使用Java运算符 3.1.1 优先级 3.1.2 赋值 3.1.3 算术运算符 3.1.4 自动递增和递减 3.1.5 关系运算符 3.1.6 逻辑运算符 3.1.7 按位运算符 3.1.8 移位运算符 3.1.9 三元if-else运算符 3.1.10 逗号运算符 3.1.11 ...

Global site tag (gtag.js) - Google Analytics