天天看點

synchronized同步函數

java線程同步機制的方式:

方式二:同步函數就是synchronized修飾一個函數

同步函數需要注意的事項:

    1.非靜态的同步函數的鎖對象是this對象,靜态的同步函數的鎖對象是目前函數所屬的類的位元組碼檔案(class對象)

    2.同步函數的 鎖對象是固定的,不能由你來指定。

推薦使用:同步代碼塊

原因:1.同步代碼塊的鎖對象可以由我們随意指定,友善控制。同步函數的鎖對象是固定的,不能由我們來指定。

package com.cn.thread;
/**
* Author:Liu Zhiyong
* Version:Version_1
* Date:2016年7月5日12:30:36
* Desc:方式二:同步函數
* 
* 同步函數需要注意的事項:
*   1.如果一個非靜态的同步函數的鎖對象是this對象,如果是靜态的同步函數的鎖對象是目前函數所屬的類的位元組碼檔案(class對象)
*   2.同步函數的 鎖對象是固定的,不能由你來指定。
*   
* 推薦使用:同步代碼塊
*   原因:1.同步代碼塊的鎖對象可以由我們随意指定,友善控制。同步函數的鎖對象是固定的,不能由我們來指定。
*     2.同步代碼塊可以很友善的控制需要被同步代碼的範圍,同步函數必須是整個函數的所有的代碼都被同步了。
*/
class  BankThread extends Thread{
  static int allMoney = 5000;//銀行總共的錢
  public BankThread(String name) {
    super(name);
  }
  @Override
  public  void run() {
    getMoney();
    
//    while(true){
      synchronized("鎖"){
//        if(allMoney > 0){
//          BankThread.allMoney -= 1000;
//            System.out.println(BankThread.currentThread().getName() + "取了" + 1000 + ",還剩" + allMoney);
//        }else{
//          System.out.println("錢取光了。。。");
//          break;
//        }
      }
//    }
//  //  需要執行的代碼
//  //  需要執行的代碼
//  //  需要執行的代碼
//  //  需要執行的代碼
//  //  需要執行的代碼
//  //  需要執行的代碼
//  //  需要執行的代碼
//  //  需要執行的代碼
  }
  //靜态的函數。。函數所屬的類的位元組碼檔案對象(BankThread.class),鎖對象是唯一的。
  public static synchronized void getMoney(){
    while(true){
//      synchronized("鎖"){
        if(allMoney > 0){
          BankThread.allMoney -= 1000;
            System.out.println(BankThread.currentThread().getName() + "取了" + 1000 + ",還剩" + allMoney);
        }else{
          System.out.println("錢取光了。。。");
          break;
        }
//      }
    }
  }
}
public class Demo6 {
  public static void main(String[] args) {
    BankThread h = new BankThread("丈夫");
    h.start();
    BankThread w = new BankThread("妻子");
    w.start();
  }
}