有一个帐户,多个用户(线程)在同时操做这个帐户,有的存款有的取款,存款随便存,取款有限制,不能透支,任何试图透支的操做都将等待里面有足够存款才执行操做。 java
若是程序不使用synchronized关键字来保证同步,而直接用lock.那么系统中不存在隐式的同步监视器,就不能使用wait,notify,notifyAll方法进行线程通讯了.但使用Lock对象来保证同步时,Java提供了一个Condition类来保持协调,使用Condition可让那些已经获得Lock对象但没法继续执行的线程释放Lock对象,Condition对象也能够唤醒其余等待的线程.这状况下,Lock替代了同步方法或同步代码块,Condition替代了同步监视器的功能. 安全
Condition实例绑定在Lock对象上,要得到须要调用Lock对象的newCondition方法.有3个方法:
多线程
package com.thread.lock; import java.util.concurrent.locks.Condition; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; public class MyCount { private String id; // 帐号 private int cash; // 帐户余额 private Lock lock = new ReentrantLock(); // 帐户锁 private Condition _save = lock.newCondition(); // 存款条件 private Condition _draw = lock.newCondition(); // 取款条件 MyCount(String id, int cash) { this.id = id; this.cash = cash; } /** * 存款 * * @param name * 存款人姓名 * @param cash * 存款金额 */ public void saving(String name, int saveCash) { lock.lock(); if (saveCash > 0) { cash += saveCash; System.out.println(name + " 存款 " + saveCash + ",当前余额为" + cash); } _draw.signalAll(); // 唤醒全部等待线程。 lock.unlock(); // 释放锁 } /** * 取款 * * @param name * 取款人姓名 * @param cash * 取款金额 */ public void drawing(String name, int saveCash) { lock.lock(); try { if (cash < saveCash) { _draw.await(); // 阻塞取款操做 } else { cash -= saveCash;// 取款 System.out.println(name + " 取款 " + saveCash + ",当前余额为" + cash); } _save.signalAll(); // 唤醒全部存款操做 } catch (InterruptedException e) { System.out.println(name + " 取款超额了" + " 取款金额为:" + saveCash); // TODO Auto-generated catch block // e.printStackTrace(); } finally { lock.unlock(); } } } class DrawThread extends Thread { private String name; // 操做人 private MyCount myCount; // 帐户 private int saveCash; // 存款金额 DrawThread(String name, MyCount myCount, int saveCash) { this.name = name; this.myCount = myCount; this.saveCash = saveCash; } @Override public void run() { myCount.drawing(name, saveCash); } } class SaveThread extends Thread { private String name; // 操做人 private MyCount myCount; // 帐户 private int saveCash; // 存款金额 SaveThread(String name, MyCount myCount, int saveCash) { this.name = name; this.myCount = myCount; this.saveCash = saveCash; } @Override public void run() { myCount.saving(name, saveCash); } } package com.thread.lock; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; public class TestLock { public void run(){ ExecutorService pool = Executors.newFixedThreadPool(5); MyCount count = new MyCount("43089183736746383", 1200); SaveThread save1 = new SaveThread("张三",count, 200); SaveThread save2 = new SaveThread("李四",count, 100); DrawThread draw1 = new DrawThread("王五", count, 1600); DrawThread draw2 = new DrawThread("赵六", count, 500); SaveThread save3 = new SaveThread("王杰",count, 3000); pool.execute(save1); pool.execute(save2); pool.execute(draw1); pool.execute(draw2); pool.execute(save3); pool.shutdownNow(); } public static void main(String[] args) { new TestLock().run(); } }