java线程死锁研究

线程死锁:

       a线程锁定了1号资源,下一步需要锁定2号资源。

       b线程锁定了2号资源,下一步需要锁定1号资源。

       两个线程无限制的等待下去,于是就出现了死锁。

引用网上的实例:

     

package test;

public class TestDeadLock extends Thread {
	static Object o1 = new Object(), o2 = new Object();
	int flag = 0;
	public void run() {
		if(flag == 0){
			synchronized (o1) {
				System.out.println("a锁定了刀,想要叉");
				try {
					this.sleep(500);
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
				synchronized (o2){
					System.out.println("a 要叉成功");
				}
			}
		}
		if(flag == 1){
			synchronized (o2) {
				System.out.println("b锁定了叉,想要刀");
				try {
					this.sleep(500);
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
				synchronized (o1){
					System.out.println("b 要刀成功");
				}
			}
		}
	}
	public static void main(String[] args) {
		TestDeadLock tdl1 = new TestDeadLock();
		TestDeadLock tdl2 = new TestDeadLock();
		tdl1.flag = 0;
		tdl2.flag = 1;
		tdl1.start();
		tdl2.start();
	}
}

避免死锁的方法:

        1.让所有的线程按照同样的顺序获得一组锁。这种方法消除了a和b的拥有者分别等待对方的资源的问题。

        2.将多个锁组成一组并放到同一个锁下。前面Java线程死锁的例子中,可以创建一个银器对象的锁。于是在获得刀或叉之前都必须获得这个银器的锁。

        3.将那些不会阻塞的可获得资源用变量标志出来。当某个线程获得银器对象的锁时,就可以通过检查变量来判断是否整个银器集合中的对象锁都可获得。如果是,它就可以获得相关的锁,否则,就要释放掉银器这个锁并稍后再尝试。

修改方法1:

package test;

public class TestDeadLock extends Thread {
	static Object o1 = new Object(), o2 = new Object();
	int flag = 0;
	String threadName;
	public TestDeadLock(String threadName){
		this.threadName = threadName;
		
	}
	/**
	 * 把两个方法合并到一个同步块中
	 */
	public synchronized void getCanju(){
		System.out.println(threadName+"锁定了刀,想要叉");
		try {
			this.sleep(500);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		System.out.println(threadName+"要叉成功");
		
	}
	public void run() {
	
			getCanju();


	}
	public static void main(String[] args) {
		TestDeadLock tdl1 = new TestDeadLock("线程1");
		TestDeadLock tdl2 = new TestDeadLock("线程2");
		tdl1.start();
		tdl2.start();
	}
}


原文地址:https://www.cnblogs.com/bestdata/p/3199794.html