Posted on 2009-06-02 20:14
啥都寫點 閱讀(178)
評論(0) 編輯 收藏 所屬分類:
J2SE
關鍵技術:
- 在類的方法聲明中使用synchronized關鍵字可以保證在同一時刻只有一個線程能夠進入該方法。
- synchronized可以出現在代碼塊中,表示同一時刻只有一個線程能夠進入該段代碼。
package book.thread;
/**
* 線程的互斥,主要展示同步方法與非同步方法的區別
*/
public class Synchronized {
/**
* 帳號類
*/
static class Account{
//共享資源, 錢數
private double money = 1000.0d;
/**
* 存錢 沒有同步機制
* @param fFees
*/
public void nonSynDeposit(double fFees){
System.out.println("Account nonSynDeposit begin! money = " + this.money + "; fFees = " + fFees);
//存錢錢先等待300毫秒
System.out.println("Account nonSynDeposit sleep begin!");
try {
Thread.sleep(300);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Account nonSynDeposit sleep end!");
this.money = this.money + fFees;
System.out.println("Account nonSynDeposit end! money = " + this.money);
}
/**
* 取錢 沒有同步機制
* @param fFees
*/
public void nonSynWithdraw(double fFees){
System.out.println("Account nonSynWithdraw begin! money = " + this.money + "; fFees = " + fFees);
//取錢時先等待400毫秒
System.out.println("Account nonSynWithdraw sleep begin!");
try {
Thread.sleep(400);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Account nonSynWithdraw sleep begin!");
this.money = this.money - fFees;
System.out.println("Account nonSynWithdraw end! money = " + this.money);
}
/**
* 存錢 有同步機制
* @param fFees
*/
public synchronized void synDeposit(double fFees){
System.out.println("Account synDeposit begin! money = " + this.money + "; fFees = " + fFees);
//存錢錢先等待300毫秒
System.out.println("Account synDeposit sleep begin!");
try {
Thread.sleep(300);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Account synDeposit sleep begin!");
this.money = this.money + fFees;
System.out.println("Account synDeposit end! money = " + this.money);
}
/**
* 取錢 有同步機制
* @param fFees
*/
public synchronized void synWithdraw(double fFees){
System.out.println("Account synWithdraw begin! money = " + this.money + "; fFees = " + fFees);
//取錢時先等待400毫秒
System.out.println("Account synWithdraw sleep begin!");
try {
Thread.sleep(400);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Account synWithdraw sleep end!");
this.money = this.money - fFees;
System.out.println("Account synWithdraw end! money = " + this.money);
}
}
static class AccessThread extends Thread{
//待訪問的帳號對象
private Account account = null;
//訪問帳號的方法
private String method = "";
public AccessThread(Account account, String method){
this.method = method;
this.account = account;
}
public void run(){
//對不同的方法名參數調用不同的方法
if (method.equals("nonSynDeposit")){
account.nonSynDeposit(500.0);
} else if (method.equals("nonSynWithdraw")){
account.nonSynWithdraw(200.0);
} else if (method.equals("synDeposit")){
account.synDeposit(500.0);
} else if (method.equals("synWithdraw")){
account.synWithdraw(200.0);
}
}
}
public static void main(String[] args) {
//待操作的帳號對象,所有操作都針對該帳號
Account account = new Account();
System.out.println("使用非同步方法時:");
//非同步方法存錢的線程
Thread threadA = new AccessThread(account, "nonSynDeposit");
//非同步方法取錢的線程
Thread threadB = new AccessThread(account, "nonSynWithdraw");
threadA.start();
threadB.start();
//等待兩線程運行結束
try {
threadA.join();
threadB.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
//下面測試同步方法
System.out.println();
account = new Account();
System.out.println("使用同步方法時:");
threadA = new AccessThread(account, "synDeposit");
threadB = new AccessThread(account, "synWithdraw");
threadA.start();
threadB.start();
}
}
--
學海無涯