1. 程式人生 > >Java 併發控制例項 (銀行問題取錢存錢)

Java 併發控制例項 (銀行問題取錢存錢)

併發主要的就是解決同步問題。

如果資料不同步,如假設A的銀行餘額為500。A用網銀取了500,同時用ATM機取了500,那A將會有概率總共取得1000(因為網銀與ATM是獨立的,出現網銀取錢了,但還未扣款,或者扣了錢但資料還沒反饋到總伺服器,然後ATM的得的資料還是原來的資料,即餘額任然為500,所以依然可以取出500,500+500=1000).

所以需要併發控制來解決問題,此例項採用Java 中 的 synchroniezd實現同步

package com.asmn.bank;

import static com.asmn.tools.Tools.*;

public class Main {
	public static void main(String[] args) {
		//初始餘額為500
		Bank bank = new Bank(500);
		char []names = "ABCDEF".toCharArray();
		for(char name : names){
			new Thread(new reduce(bank,name,50)).start();
		}
		for(char name : names){
			new Thread(new Add(bank,name,50)).start();
		}
	}
}

class Add implements Runnable {
	private Bank bank;
	private int sum;
	private char name;
	
	public Add(Bank bank, char name, int sum){
		this.bank = bank;
		this.sum = sum;
		this.name = name;
	}
	
	@Override
	public void run() {
		try {
			bank.add("加"+name, sum);
			Thread.sleep(500);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
	}
}

class reduce implements Runnable {
	private Bank bank;
	private int sum;
	private char name;
	
	public reduce(Bank bank, char name, int sum){
		this.bank = bank;
		this.sum = sum;
		this.name = name;
	}
	
	@Override
	public void run() {
		try {
			bank.reduce("減"+name,sum);
			Thread.sleep(500);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
	}
}
package com.asmn.bank;

import static com.asmn.tools.Tools.*;

public class Bank {
	private int money = 0;
	
	public Bank(int money){
		this.money = money;
	}
	
	public synchronized int getMoney(){
		return money;
	}
	
	public synchronized void add(String name, int sum){
		money += sum;
		pl(name+"加了"+sum+",剩餘"+money);
	}
	
	public synchronized boolean reduce(String name, int sum){
		if(sum > money){
			pl("錢不夠扣");
			return false;
		}
		
		
		money -= sum;
		pl(name+"剪了"+sum+",剩餘"+money);
		return true;
	}
	
}

可將Bank類中的synchronized關鍵字刪除和不刪除進行比較輸出結果