2014年4月9日 星期三

Thread 執行緒:同步 Synchronized

未同步化的程式
class Company {
   private int total = 0;
   
   public void add(String name, int revenue) {
    int tmp = total;
    System.out.println("司機:" + name+ " 查詢餘額:" + tmp);
    System.out.println("司機:" + name+ " 今日存入:" + revenue);
    tmp += revenue;
    System.out.println("公司:"+ "總共存款餘額:" + tmp);
    total = tmp;
    
   }
}

class Driver extends Thread {
 private Company comp;
 String name;
 
 public Driver(Company comp,String name){
  this.comp = comp;
  this.name = name;
 }
 
 public void run() {
  for(int i=0; i < 3; i++){  
   try {
    sleep(1000);
   } catch (InterruptedException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
   }
   comp.add(name,100);
  }
 }
}

public class ThreadSynchronized {
 public static void main(String[] args) {
  Company comp = new Company();
  Driver driver1 = new Driver(comp,"Driver1");
  driver1.start();
  
  Driver driver2 = new Driver(comp,"Driver2");
  driver2.start();  
 }
}


執行結果,發生什麼錯誤?





















這情況發生在當某個執行緒正在執行 add() 時,其他執行緒也正同時呼叫執行 add()。要避免此現象,必須在 add() 加入關鍵字 synchronized,這樣同步化之後就不會有資料相抵觸的情形發生。
class Company {
   private int total = 0;
   
   public synchronized void add(String name, int revenue) {
    int tmp = total;
    System.out.println("司機:" + name+ " 查詢餘額:" + tmp);
    System.out.println("司機:" + name+ " 今日存入:" + revenue);
    tmp += revenue;
    System.out.println("公司:"+ "總共存款餘額:" + tmp);
    total = tmp;
    
   }
}
執行結果





















沒有留言:

張貼留言