有一個帳戶,多個用戶(線程)在同時操做這個帳戶,有的存款有的取款,存款隨便存,取款有限制,不能透支,任何試圖透支的操做都將等待裏面有足夠存款才執行操做。 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(); } }