Condition接口可以用于协调线程之间的交互
示例:创建并启动两个线程,一个用来向账户中存款,另一个从同一账户提款。当提款的数额大于账户的当前余额时,提款线程必须等待。不管什么时候,只要向账户新存入一笔资金,存储线程必须通知提款线程重新尝试。如果余额仍未达到提款的数额,提款线程必须继续等待新的存款。
创建锁上的条件:
Lock lock = new ReentrantLock();
Condition newDeposit = lock.newCondition();
Account.java
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class Account {
private int balance;
private Lock lock = new ReentrantLock();
private Condition newDeposit = lock.newCondition();
public int getBalance(){
return balance;
}
public void withdraw(int amount) throws InterruptedException{
lock.lock();
while (balance < amount){
newDeposit.await();
}
balance -= amount;
System.out.println("提款" + amount + "元" + "\t\t\t\t\t余额" + balance );
lock.unlock();
}
public void deposit(int amount){
lock.lock();
balance += amount;
System.out.println("\t\t 存款" + amount + "元" + "\t\t\t余额" + balance);
newDeposit.signal();
lock.unlock();
}
}
说明: await()方法会释放锁,让其他线程访问竞争的资源。当前线程则变为阻塞状态,在当前代码处等待,直到被其他线程通过signal()方法唤醒,此时当前线程将会再次获得锁,并往下执行。
测试类(一):使用静态内部类编写两个线程
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class ThreadCooperationByStaticClass {
private static Account account = new Account();
public static void main(String[] a){
ExecutorService executor = Executors.newCachedThreadPool();
System.out.println("提款任务 \t\t 存款任务 \t\t 余额 " );
System.out.println("------------------------------------------------" );
executor.execute(new DepositTask());
executor.execute(new WithdrawTask());
executor.shutdown();
}
public static class DepositTask implements Runnable{
@Override
public void run() {
while (true){
account.deposit((int)(Math.random() * 10) + 1);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
public static class WithdrawTask implements Runnable{
@Override
public void run() {
try {
while (true){
account.withdraw((int)(Math.random() * 10) + 1);
}
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
结果显示:
测试类(二):使用非静态内部类编写两个线程
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class ThreadCooperationByNormalClass {
private Account account = new Account();
public static void main(String[] a) throws InterruptedException{
ExecutorService executor = Executors.newCachedThreadPool();
System.out.println("提款任务 \t\t 存款任务 \t\t 余额 " );
System.out.println("------------------------------------------------" );
ThreadCooperationByNormalClass outer = new ThreadCooperationByNormalClass();
executor.execute(outer.new DepositTask());
executor.execute(outer.new WithdrawTask());
Thread.sleep(4000);
executor.shutdown();
}
public class DepositTask implements Runnable{
@Override
public void run() {
while (true){
account.deposit((int)(Math.random() * 10) + 1);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
System.out.println("线程被关闭");
}
}
}
}
public class WithdrawTask implements Runnable{
@Override
public void run() {
try {
while (true){
account.withdraw((int)(Math.random() * 10) + 1);
}
} catch (InterruptedException e) {
// TODO Auto-generated catch block
System.out.println("线程被关闭");
}
}
}
}