一个线程可以指定在某种条件下该做什么。条件是通过调用Lock对象的newCondition()方法而创建的对象。一旦创建了条件,就可以使用await()、signal()和signalAll()方法来实现线程间的互相通信。await()方法可以让当前线程都处于等待状态,直到条件发生。signal()方法唤醒一个等待的线程,而signalAll()方法唤醒所有等待的线程。
例:两个线程同时运行一下两个方法
private static Lock lock = new ReentrantLock();
private static Condition newDeposit = lock.newCondition();
private int balance = 0;
public void withDraw(int amount){
lock.lock();
try{
while(balance < amount){
System.out.println("\t\t\tWait for a deposit");
newDeposit.await();
}
balance -= amount;
System.out.println("\t\t\tWithDraw " + amount + "\t\t" + getBalance());
} catch (InterruptedException e) {
e.printStackTrace();
}finally {
lock.unlock();
}
}
public void deposit(int amount){
lock.lock();
try{
balance += amount;
System.out.println("Deposit " + amount + "\t\t\t\t\t" + getBalance());
newDeposit.signalAll();
}finally {
lock.unlock();
}
}
可以看出,当balance的值小于amount时会调用await()方法进入等待状态,直到deposit方法中调用了signalAll()方法,withDraw方法才继续执行。
为了判断调用signalAll()方法后是从withDraw()方法的什么地方开始重新执行这个问题,在进入withDraw()方法后的第一行加入输出一条判断语句
public void withDraw(int amount){
System.out.println("---------Method withDraw run---------");
lock.lock();
try{
while(balance < amount){
System.out.println("\t\t\tWait for a deposit");
newDeposit.await();
}
balance -= amount;
System.out.println("\t\t\tWithDraw " + amount + "\t\t" + getBalance());
} catch (InterruptedException e) {
e.printStackTrace();
}finally {
lock.unlock();
}
}
重新运行程序
可以看出balance-amount之后重新调用一次withDraw方法进行下一次减数,balance小于amount后等待deposit方法,deposit方法中signalAll()唤醒withDraw之后并没有从方法的第一行开始执行,直接输出了Wait for a deposition,等待deposition方法,由此可知调用signalAll()方法后将从await()方法开始继续执行之后的逻辑。