今天看到一段关于synchronized的小代码,比较有意思。当将S1的static去掉,这个死锁便解开了。其实也很好理解,线程1进入后锁住S1,并且等待了500,在等待时线程2来了,锁住了S2。线程1的500过了后接着锁住S2开始下面的输出,但是S2被线程2锁住不放;同样线程2锁住了S2,接着去取S1的控制权,但是线程1却握着不放。死锁便产生了。S1和S2都是static关键字修饰,他们都是共享内存空间,去掉这个关键字,那么线程1和线程2锁住的不是同一个对象了,问题也不会产生。每个对象都包含了一把锁(也叫作“监视器”),它自动成为对象的一部分(不必为此写任何特殊的代码)。调用任何synchronized方法时,对象就会被锁定,不可再调用那个对象的其他任何synchronized方法,除非第一个方法完成了自己的工作,并解除锁定。
package com.example.thread2;
public class TestDeadLock implements Runnable {
public int flag = 1;
static Object S1 = new Object();
static Object S2 = new Object();
public String threadId;
public TestDeadLock(String s){
threadId = s;
}
public void run() {
System.out.println(threadId + ":flag=" + flag);
if (flag == 1) {
synchronized (S1) {
try {
Thread.sleep(500);
} catch (Exception e) {
e.printStackTrace();
}
synchronized (S2) {
System.out.println("1");
}
}
}
if (flag == 0) {
synchronized (S2) {
try {
Thread.sleep(500);
} catch (Exception e) {
e.printStackTrace();
}
synchronized (S1) {
System.out.println("0");
}
}
}
}
public static void main(String[] args) {
TestDeadLock td1 = new TestDeadLock("No.1");
TestDeadLock td2 = new TestDeadLock("No.2");
td1.flag = 1;
td2.flag = 0;
Thread t1 = new Thread(td1);
Thread t2 = new Thread(td2);
t1.start();
t2.start();
}
}