一、帳戶類java
package com.ljb.app.synchronize; /** * 模擬帳戶類(線程同步必要性) * @author LJB * @version 2015年3月10日 */ public class Account { // 餘額 private int balance = 500; // 查詢餘額 public int getBalance() { return balance; } // 取款(這裏沒有設置餘額判斷<餘額大於0,餘額足夠支付取款數量>) public void withdraw (int amount) { balance = balance - amount; } }
二、取款線程(擁有同一個帳戶)app
package com.ljb.app.synchronize; /** * 取款線程(模擬動態取款) * @author LJB * @version 2015年3月10日 */ public class WithdrawThread implements Runnable{ /* * 全部用此對象建立的線程共享同一個帳戶 */ private Account account = new Account(); /* * 取款、查詢餘額(non-Javadoc) * @see java.lang.Runnable#run() */ public void run () { for (int i = 0 ; i < 5 ; i++) { // 取款 makeWithdraw(100); // 查詢餘額 if (account.getBalance() < 0) { System.out.println("帳戶透支了!"); } } } /* * 取款 (餘額不足給出提示) */ private void makeWithdraw (int amount) { if (account.getBalance() >= amount) { System.out.println(Thread.currentThread().getName() + "準備取款。"); try { Thread.sleep(500); } catch (InterruptedException e) { e.printStackTrace(); } // 0.5秒以後完成取款 account.withdraw(amount); System.out.println(Thread.currentThread().getName() + "完成取款。"); } else { System.out.println("餘額不足以支付" + Thread.currentThread().getName() + "的取款,餘額爲" + account.getBalance()); } } }
三、測試類測試
package com.ljb.app.synchronize; /** * 建立2個線程同時使用同一個帳戶 * @author LJB * @version 2015年3月10日 */ public class TestWithdraw { /** * @param args */ public static void main(String[] args) { // 建立實現Runnable接口類實例 WithdrawThread withdraw = new WithdrawThread(); // 建立2個線程 Thread husband = new Thread(withdraw); Thread wife = new Thread(withdraw); husband.setName("丈夫"); wife.setName("妻子"); husband.start(); wife.start(); } }
運行結果:spa
丈夫準備取款。
妻子準備取款。
妻子完成取款。
妻子準備取款。
丈夫完成取款。
丈夫準備取款。
妻子完成取款。
妻子準備取款。
丈夫完成取款。
丈夫準備取款。
妻子完成取款。
丈夫完成取款。
妻子準備取款。
丈夫準備取款。
丈夫完成取款。
帳戶透支了!
妻子完成取款。
帳戶透支了!
餘額不足以支付妻子的取款,餘額爲-100
帳戶透支了!
餘額不足以支付丈夫的取款,餘額爲-100
帳戶透支了!
四、同步方法線程
/* * 取款 (餘額不足給出提示) */ private synchronized void makeWithdraw (int amount) { if (account.getBalance() >= amount) { System.out.println(Thread.currentThread().getName() + "準備取款。"); try { Thread.sleep(500); } catch (InterruptedException e) { e.printStackTrace(); } // 0.5秒以後完成取款 account.withdraw(amount); System.out.println(Thread.currentThread().getName() + "完成取款。"); } else { System.out.println("餘額不足以支付" + Thread.currentThread().getName() + "的取款,餘額爲" + account.getBalance()); } }
運行結果:code
丈夫準備取款。
丈夫完成取款。
妻子準備取款。
妻子完成取款。
妻子準備取款。
妻子完成取款。
妻子準備取款。
妻子完成取款。
丈夫準備取款。
丈夫完成取款。
餘額不足以支付丈夫的取款,餘額爲0
餘額不足以支付丈夫的取款,餘額爲0
餘額不足以支付丈夫的取款,餘額爲0
餘額不足以支付妻子的取款,餘額爲0
餘額不足以支付妻子的取款,餘額爲0
對象
五、同步代碼塊(比同步方法更強大)接口
/* * 取款 (餘額不足給出提示) */ private void makeWithdraw (int amount) { synchronized (account) { if (account.getBalance() >= amount) { System.out.println(Thread.currentThread().getName() + "準備取款。"); try { Thread.sleep(500); } catch (InterruptedException e) { e.printStackTrace(); } // 0.5秒以後完成取款 account.withdraw(amount); System.out.println(Thread.currentThread().getName() + "完成取款。"); } else { System.out.println("餘額不足以支付" + Thread.currentThread().getName() + "的取款,餘額爲" + account.getBalance()); } } }