在Object的wait,notify,notifyAll上做了一层封装,时锁的控制更细化。条件变量的出现是为了更精细的控制线程等待与唤醒,一个锁可以有多个条件,每个条件上有多个线程等待,通过await()方法,可以让线程在该条件下等待。当调用signalAll()方法时,又可以唤醒该条件下等待的线程
import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.locks.Condition; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; /** * Java线程:条件变量 * * @author leizhimin 2009-11-5 10:57:29 */ public class Test1 { public static void main(String[] args) { //创建并发访问的账户 MyCount myCount = new MyCount("95599200901215522", 10000); //创建一个线程池 ExecutorService pool = Executors.newFixedThreadPool(6); Thread t1 = new SaveThread("张三", myCount, 1); Thread t2 = new SaveThread("李四", myCount, 2); Thread t3 = new SaveThread("王五", myCount, 3); Thread t4 = new DrawThread("老张", myCount, 4); Thread t5 = new DrawThread("老牛", myCount, 5); Thread t6 = new DrawThread("胖子", myCount, 6); //执行各个线程 pool.execute(t1); pool.execute(t2); pool.execute(t3); pool.execute(t4); pool.execute(t5); pool.execute(t6); //关闭线程池 pool.shutdown(); } } /** * 存款线程类 */ class SaveThread extends Thread { private String name; //操作人 private MyCount myCount; //账户 private int x; //存款金额 SaveThread(String name, MyCount myCount, int x) { this.name = name; this.myCount = myCount; this.x = x; } public void run() { myCount.saving(x, name); } } /** * 取款线程类 */ class DrawThread extends Thread { private String name; //操作人 private MyCount myCount; //账户 private int x; //存款金额 DrawThread(String name, MyCount myCount, int x) { this.name = name; this.myCount = myCount; this.x = x; } public void run() { myCount.drawing(x, name); } } /** * 普通银行账户,不可透支 */ class MyCount { private String oid; //账号 private int cash; //账户余额 private Lock lock = new ReentrantLock(); //账户锁 public Condition _save = lock.newCondition(); //存款条件 public Condition _draw = lock.newCondition(); //取款条件 MyCount(String oid, int cash) { this.oid = oid; this.cash = cash; } public static void sleep() { try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } } /** * 存款 * * @param x 操作金额 * @param name 操作人 */ public void saving(int x, String name) { try { lock.lock(); //获取锁 _save.await(); // 等待存钱通知 _draw.signal(); // 存钱后通知取钱 cash += x; //存款 sleep(); System.out.println(name + "存款" + x + ",当前余额为" + cash); lock.unlock(); //释放锁 } catch (InterruptedException e) { } } /** * 取款 * * @param x 操作金额 * @param name 操作人 */ public void drawing(int x, String name) { try { lock.lock(); //获取锁 if (x == 6) { _save.signal(); // 当取钱是6时,触发存钱 } else { _draw.await(); // 取钱不是6时,等待 _save.signal(); // 去前后触发存钱 } cash -= x; //取款 sleep(); System.out.println(name + "取款" + x + ",当前余额为" + cash); } catch (Exception e) { e.printStackTrace(); } finally { lock.unlock(); //释放锁 } } }