Javaマルチスレッド:スレッドデッドロック


デッドロックの原因は、通常、2つのオブジェクトのロックが互いに待機しているためです.次の例を使用して、このような状況を構築します.
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のリソースを待機します.2つのスレッドが互いに待機しており、デッドロックが発生します.