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