前段时间review同事的代码,发现可以简化成如下的模型:
Thread 1 | Thread 2 |
lock.lock(); condition.await(); lock.unlock() |
lock.lock(); condition.signal(); lock.unlock(); |
怀疑是个死锁。写了下面这个case模拟了一下,却没有问题。
但是T2为何能进入signal呢?
根据javadoc的文档,这明显是第三种情况:
public void lock()
- Acquires the lock.
Acquires the lock if it is not held by another thread and returns immediately, setting the lock hold count to one.
If the current thread already holds the lock then the hold count is incremented by one and the method returns immediately.
If the lock is held by another thread then the current thread becomes disabled for thread scheduling purposes and lies dormant until the lock has been acquired, at which time the lock hold count is set to one.
原来是因为T1进入await了,那么这个条件上的lock就自动释放了,文档如下:
void await() throws InterruptedException
Causes the current thread to wait until it is signalled or interrupted.
The lock associated with this Condition
is atomically released and the current thread becomes disabled for thread scheduling purposes and lies dormant until one of four things happens:
代码如下:
import java.util.Date;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class LockTest {
Lock lock = new ReentrantLock();
Condition finishCondition = lock.newCondition();
class T1 implements Runnable {
public void run() {
try {
lock.lock();
System.out.println("enter T1:" + new Date());
try {
finishCondition.await();
System.out.println("end wating T1:" + new Date());
} catch (Exception ex) {
ex.printStackTrace();
}
} finally {
lock.unlock();
System.out.println("exit T1:" + new Date());
}
}
}
class T2 implements Runnable {
public void run() {
try {
lock.lock();
System.out.println("enter T2:" + new Date());
try {
Thread.sleep(1000);
finishCondition.signal();
} catch (Exception ex) {
ex.printStackTrace();
}
} finally {
lock.unlock();
System.out.println("exit T2:" + new Date());
}
}
}
public void run() throws Exception {
new Thread(new T1()).start();
Thread.sleep(50);
new Thread(new T2()).start();
}
public static void main(String[] args) throws Exception {
LockTest lt = new LockTest();
lt.run();
Thread.sleep(3000);
System.out.println("exit main.");
}
}
http://www.cnblogs.com/alphablox/archive/2013/01/13/2858264.html