Java併發學習之十一——同步方法

本文是學習網絡上的文章時的總結,感謝大家無私的分享。 

每個方法聲明爲synchronized關鍵字是一個臨界區,Java只允許一個對象執行其中的一個臨界區。

靜態方法有不同的行爲。只有一個執行線程訪問被synchronized關鍵字聲明的靜態方法,但另一個線程可以訪問該類的一個對象中的其他非靜態的方法。 你必須非常小心這一點,因爲兩個線程可以訪問兩個不同的同步方法,如果其中一個是靜態的而另一個不是。如果這兩種方法改變相同的數據,你將會有數據不一致 的錯誤。

package chapter2;

public class Account {

	private double balance;

	public double getBalance() {
		return balance;
	}

	public void setBalance(double balance) {
		this.balance = balance;
	}
	
	public synchronized void addAmount(double amount){
		double tmp = balance;
		try {
			Thread.sleep(10);
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		tmp+=amount;
		balance = tmp;
	}
	
	public synchronized void subtractAmount(double amount){
		double tmp = balance;
		try {
			Thread.sleep(10);
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		tmp-=amount;
		balance=tmp;
	}
	
	
}

package chapter2;

public class Bank implements Runnable{

	private Account account;
	public Bank(Account account) {
		this.account = account;	
	}
	
	@Override
	public void run() {
		// TODO Auto-generated method stub
		for(int i=0;i<100;i++){
			account.subtractAmount(1000);
		}
	}

}
package chapter2;

public class Company implements Runnable{

	private Account account;
	public Company(Account account) {
		this.account = account;	
	}
	
	@Override
	public void run() {
		// TODO Auto-generated method stub
		for(int i=0;i<100;i++){
			account.addAmount(1000);
		}
	}

}


package chapter2;

public class Main {

	/**
	 * <p>
	 * </p>
	 * @author zhangjunshuai
	 * @date 2014-9-11 下午4:49:50
	 * @param args
	 */
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Account account = new Account();
		account.setBalance(1000);
		Company company = new Company(account);
		Thread companyThread = new Thread(company);
		Bank bank = new Bank(account);
		Thread bankThread = new Thread(bank);
		System.out.printf("Account:Initial balance:%f\n", account.getBalance());
		companyThread.start();
		bankThread.start();
		try {
			companyThread.join();
			bankThread.join();
			System.out.printf("Account:Initial balance:%f\n", account.getBalance());
		} catch (Exception e) {
			// TODO: handle exception
			e.printStackTrace();
		}
	}

}




發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章