Java基礎複習:線程同步練習

來源:互聯網
上載者:User

題目:類比銀行取款,使用三種線程同步方法實現取款的安全。編寫如下類,並進行取款測試:

賬戶類:Account,含餘額欄位balance

取款類:DrawMoney,在指定帳戶中進行取款操作

編寫線程體:實現取款操作的安全

 

方法1:同步代碼塊

/** * 銀行帳戶 */class Account {/** * 餘額 */private double balance;/** * 構造方法 * @param balance */Account(double balance) {super();this.balance = balance;}//getter . setterpublic double getBalance() {return balance;}public void setBalance(double balance) {this.balance = balance;}}class ATM implements Runnable{/** * 需要取的金額 */private double drawMoney;String str = new String("");//做同步代碼塊的監聽對象/** * 帳戶 */private Account a;ATM(double drawMoney, Account a) {super();this.drawMoney = drawMoney;this.a = a;}public void run() {synchronized (str) {if(a.getBalance()>=drawMoney){System.out.println(Thread.currentThread().getName()+"吐出了"+drawMoney+"元");a.setBalance(a.getBalance()-drawMoney);//修改餘額}else{System.out.println("Your account don't have enough money!");}}}}public class DrawMoneyDemo {public static void main(String[] args) {Account a = new Account(1000);ATM atm = new ATM(800,a);//從a帳戶中取800元//假設有兩個線程進行同時操作new Thread(atm, "A").start();new Thread(atm, "B").start();}}

執行結果為:

B吐出了800.0元
Your account don't have enough money!

 

我們將具有原子性的代碼放入 synchronized 代碼塊中,形成同步代碼塊。這樣,在同一時刻只能有一個線程進入代碼塊執行該段代碼。
格式為:

synchronized(object){

//代碼塊

}

 

方法2:同步方法

在帳戶類中定義一個同步方法實現取款操作,這樣線程執行時,只能互斥的調用該方法

/** * 銀行帳戶 */class Account {/** * 餘額 */private double balance;/** * 構造方法 *  * @param balance */Account(double balance) {super();this.balance = balance;}// getter . setterpublic double getBalance() {return balance;}public void setBalance(double balance) {this.balance = balance;}/** * 使用同步方法的方式進行取款 * @param drawMoney *            取款金額 */public synchronized void draw(double drawMoney) {if (this.getBalance() >= drawMoney) {System.out.println(Thread.currentThread().getName() + "吐出了"+ drawMoney + "元");this.setBalance(this.getBalance() - drawMoney);// 修改餘額} else {System.out.println("Your account don't have enough money!");}}}class ATM implements Runnable {/** * 需要取的金額 */private double drawMoney;/** * 帳戶 */private Account a;ATM(double drawMoney, Account a) {super();this.drawMoney = drawMoney;this.a = a;}public void run() {a.draw(drawMoney);}}public class DrawMoneyDemo {public static void main(String[] args) {Account a = new Account(1000);ATM atm = new ATM(800, a);// 從a帳戶中取800元// 假設有兩個線程進行同時操作new Thread(atm, "A").start();new Thread(atm, "B").start();}}

執行結果為:

A吐出了800.0元
Your account don't have enough money!

 

 

方法3:利用Java5的同步鎖機制實現線程同步

import java.util.concurrent.locks.ReentrantLock;/** * 銀行帳戶 */class Account {/** * 餘額 */private double balance;// 定義可重新進入鎖private final ReentrantLock lock = new ReentrantLock();/** * 構造方法 *  * @param balance */Account(double balance) {super();this.balance = balance;}// getter . setterpublic double getBalance() {return balance;}public void setBalance(double balance) {this.balance = balance;}/** * 使用可重新進入鎖的方式進行取款 *  * @param drawMoney *            取款金額 */public void draw(double drawMoney) {lock.lock();// 加鎖try {if (this.getBalance() >= drawMoney) {System.out.println(Thread.currentThread().getName() + "吐出了"+ drawMoney + "元");this.setBalance(this.getBalance() - drawMoney);// 修改餘額} else {System.out.println("Your account don't have enough money!");}} finally {lock.unlock();// 釋放鎖}}}class ATM implements Runnable {/** * 需要取的金額 */private double drawMoney;/** * 帳戶 */private Account a;ATM(double drawMoney, Account a) {super();this.drawMoney = drawMoney;this.a = a;}public void run() {a.draw(drawMoney);}}public class DrawMoneyDemo {public static void main(String[] args) {Account a = new Account(1000);ATM atm = new ATM(800, a);// 從a帳戶中取800元// 假設有兩個線程進行同時操作new Thread(atm, "A").start();new Thread(atm, "B").start();}}

執行結果為:

A吐出了800.0元
Your account don't have enough money!

 

對於可重新進入鎖,其格式為:

public class X {private final ReentrantLock lock = new ReentrantLock();//定義需要保證安全執行緒的方法public void  m(){//加鎖lock.lock();try{//... method body}finally{//在finally釋放鎖lock.unlock();}}}

使用ReentrantLock可重新進入鎖對象可以顯示的加鎖和解鎖,其具有與使用synchronized方法和語句所訪問的隱式監聽器鎖相同的一些基本行為和語義,但功能更強大。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.