package com.panny.thread; public class CreditCard { private String cid; // 信用卡帳戶 private int balance; // 信用卡餘額 public CreditCard(String cid, int balance) { this.cid = cid; this.balance = balance; } public String getCid() { return cid; } public void setCid(String cid) { this.cid = cid; } public int getBalance() { return balance; } public void setBalance(int balance) { this.balance = balance; } public String toString() { return "{" + this.cid + "}"; } }
step_02:定義一個線程安全的操做類SafeOperation.java java
package com.panny.thread; import java.util.concurrent.locks.ReadWriteLock; public class SafeOperation implements Runnable { private String atm; // 執行操做的取款機名稱 private CreditCard myCard; // 執行操做的信用卡 private int ioCash; // 操做的金額 private ReadWriteLock lock; // 執行操做的對象鎖,此處爲讀寫鎖 private int operationType; // 操做類型:存款-1, 取款-2, 查詢-3 public SafeOperation(String atm, CreditCard myCard, int ioCash, ReadWriteLock lock, int operationType) { this.atm = atm; this.myCard = myCard; this.ioCash = ioCash; this.lock = lock; this.operationType = operationType; } @Override public void run() { // 根據操做類型執行動做 if(this.operationType == 1) { // 存款 makeLock(1); // 打開寫入鎖(必須) System.out.println("ATM: " + this.atm + "\n" + "CID: " + this.myCard.toString() + "\n" + "TyPE: input" + "\n" + "CURRENT_BALANCE: " + this.myCard.getBalance()+"\n" + "INPUT CASH: " + this.ioCash); try { System.out.println("Doing..."); int currBalance = this.myCard.getBalance(); this.myCard.setBalance(currBalance + this.ioCash); Thread.sleep(2000); System.out.println("SUCCESS!! ATM: " + this.atm + "\n" + "CID: " + this.myCard.toString() + "\n" + "CURRENT_BALANCE: " + this.myCard.getBalance() + "\n"); } catch (InterruptedException e) { e.printStackTrace(); } finally { unlock(1); // 關閉寫入鎖(必須) } } else if(this.operationType == 2) { makeLock(1); System.out.println("ATM: " + this.atm + "\n" + "CID: " + this.myCard.toString() + "\n" + "TyPE: output" + "\n" + "CURRENT_BALANCE: " + this.myCard.getBalance()+"\n" + "INPUT CASH: " + this.ioCash); try { System.out.println("Doing..."); int currBalance = this.myCard.getBalance(); this.myCard.setBalance(currBalance - this.ioCash); Thread.sleep(2000); System.out.println("SUCCESS!! ATM: " + this.atm + "\n" + "CID: " + this.myCard.toString() + "\n" + "CURRENT_BALANCE: " + this.myCard.getBalance() + "\n"); } catch (InterruptedException e) { e.printStackTrace(); } finally { unlock(1); } } else if(this.operationType == 3) { makeLock(2); try { System.out.println("Doing..."); Thread.sleep(2000); System.out.println("ATM: " + this.atm + "\n" + "CID: " + this.myCard.toString() + "\n" + "TyPE: query" + "\n" + "CURRENT_BALANCE: " + this.myCard.getBalance() + "\n"); } catch (InterruptedException e) { e.printStackTrace(); } finally { unlock(2); } } } /** * 根據參數類型執行打開寫入鎖(type=1),或打開讀取鎖(type=2) * @param type */ private void makeLock(int type) { switch(type) { case 1: this.lock.writeLock().lock(); break; case 2: this.lock.readLock().lock(); break; } } /** * 根據參數類型執行關閉寫入鎖(type=1),或關閉讀取鎖(type=2) * @param type */ private void unlock(int type) { switch(type) { case 1: this.lock.writeLock().unlock(); break; case 2: this.lock.readLock().unlock(); break; } } }step_03:定義一個測試類 CreditCardTest.java
package com.panny.thread; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.locks.ReentrantReadWriteLock; public class CreditCardTest { public static void main(String[] args) { CreditCard card = new CreditCard("000-111-222", 5000); ReentrantReadWriteLock lock = new ReentrantReadWriteLock(); //--------1 ExecutorService pool = Executors.newCachedThreadPool(); //------------2 SafeOperation operation1 = new SafeOperation("ATM001", card, 200, lock, 1); SafeOperation operation2 = new SafeOperation("ATM002", card, 300, lock, 2); SafeOperation operation3 = new SafeOperation("ATM003", card, 500, lock, 3); SafeOperation operation4 = new SafeOperation("ATM004", card, 100, lock, 1); pool.execute(operation1); pool.execute(operation2); pool.execute(operation3); pool.execute(operation4); pool.shutdown(); //-----------3 } }//---------1:
若是能夠明確區分讀/寫操做,那麼,建議使用讀/寫鎖來提升性能,
否則使用普通鎖:java.util.concurrent.locks.Lock和它的直接子類:ReentrantLock
//--------2:
java.util.concurrent.Executors:
建立一個線程池,根據須要建立新線程,但當他們是可用的時候,將重用先前構造的線程
//--------3:
記得關閉線程池是個好習慣 安全