天天看點

synchronized 關鍵字的了解

 1、 要保護這一段代碼, 必須将它變為臨界區,使用Java提供我們的鎖機制(同步監視控制)

2、在同一個服務線程中(不管是不是同一個任務執行體),這裡形象比喻Person(線程)上Toilet(臨界區),一次且隻能有一個人在Toilet裡,隻要Person不出來(不釋放鎖),其他人(其他線程)就不能進入。 

3、簡單來說就是:兩個人不能在一時刻擁有房間的使用權。

4、示範代碼如下:

package com.tiger.toilet;

import java.util.concurrent.TimeUnit;
/**
 * 要保護這一段代碼, 必須将它變為臨界區
 * 使用Java提供我們的鎖機制(同步監視控制)
 * 在同一個服務線程中(不管是不是同一個任務執行體),這裡形象比喻Person(線程)上Toilet(臨界區),
 * 一次且隻能有一個人在Toilet裡,隻要Person不出來(不釋放鎖),其他人(其他線程)就不能進入。
 * 
 * 簡單來說就是:兩個人不能在一時刻擁有房間的使用權。
 * @author tiger
 * @Date 2017年7月26日
 */
public class ToiletTest{
  public static void main(String[] args) {

    Toilet tagert = new Toilet();
    Thread th1 = new Thread(tagert,"老王");
    Thread th2 = new Thread(tagert,"小王");
    th1.start();
    th2.start();

    Toilet tagert2 = new Toilet();
    Thread th3 = new Thread(tagert2,"老李");
    th3.start();

    //另外一個執行體
    Hotel hotel = new Hotel();
    Thread th4 = new Thread(hotel,"大王");
    th4.start();
  }
}
/**
 * 将上廁所這件事情變為同步  -- 臨界區
 * @author tiger
 * @Date 2017年7月26日
 */
class Toilet implements Runnable{
  String lock = "lock";
  @Override
  public void run() {
    //擷取目前線程名字
    String name = Thread.currentThread().getName();
    //定義兩把鎖,激活兩把鎖
    if (name.equals("老王")) {
      this.lock = "1";
    }else{
      this.lock = "2";
    }
    //同步鎖,可以看為是密碼鎖,密碼随意配置設定,隻要不和其他的相同即可
    synchronized (lock) {
      System.out.println(name+" 持有"+lock+"卡上廁所!");
      for (int i = 0; i < 3; i++) {
        try {
          TimeUnit.SECONDS.sleep(1);
          System.out.println(name+" 在廁所呆了 "+ i+" s");
        } catch (InterruptedException e) {
          e.printStackTrace();
        }
      }
      System.out.println(name+" 從廁所出來!");
    }
  }
}

class Hotel implements Runnable{
  String lock = "2";
//  String lock = "3";
  @Override
  public void run() {
    //擷取目前線程名字
    String name = Thread.currentThread().getName();
    //同步鎖,可以看為是密碼鎖,密碼随意配置設定,隻要不和其他的相同即可
    synchronized (lock) {
      System.out.println(name+" 持有"+lock+"卡上酒店!");
      for (int i = 0; i < 6; i++) {
        try {
          TimeUnit.SECONDS.sleep(1);
          System.out.println(name+" 在酒店呆了 "+ i+" s");
        } catch (InterruptedException e) {
          e.printStackTrace();
        }
      }
      System.out.println(name+" 從酒店出來!");
    }
  }
}package com.tiger.toilet.room;

import java.util.concurrent.TimeUnit;
/**
 * 關聯上鎖(同步螢幕),同一對象的不同臨界區
 * @author tiger
 * @Date 2017年7月26日
 */
public class ToiletTest01 {
  public static void main(String[] args) {
    Task tagert = new Task();
    //一次隻能有一個人在廁所裡邊,隻有等待廁所裡邊的人出來,另外一個人才能進去。
    Thread th1 = new Thread(tagert,"老王");
    Thread th2 = new Thread(tagert,"小王");
    th1.start();
    th2.start();
  }
}
/**
 * 線程類
 * @author tiger
 * @Date 2017年7月26日
 */
class Task implements Runnable{
  Toilet toilet = new Toilet();
  //鑰匙庫
  String[] lock = {"鎖1","鎖2"};
  @Override
  public void run() {
    String name = Thread.currentThread().getName();
    //關聯上鎖
    if (name.equals("老王")) {
      toilet.room01(lock[0]);
    }else{
      toilet.room02(lock[1]);
    }
  }
}
/**
 * 廁所類
 * @author tiger
 * @Date 2017年7月26日
 */
class Toilet {
  //一号
  public void room01(String lock){
    String name = Thread.currentThread().getName();
    //同步鎖,可以看為是密碼鎖,密碼随意配置設定,隻要不和其他的相同即可
    synchronized (lock) {
      System.out.println(name+"持有 "+lock+" 上1号廁所!");
      for (int i = 0; i < 5; i++) {
        try {
          TimeUnit.SECONDS.sleep(1);
          System.out.println(name+"在廁所呆了"+ i+"s");
        } catch (InterruptedException e) {
          e.printStackTrace();
        }
      }
      System.out.println(name+"從廁所出來!");
    }
  }
  //二号
  public void room02(String lock){
    String name = Thread.currentThread().getName();
    //同步鎖,可以看為是密碼鎖,密碼随意配置設定,隻要不和其他的相同即可
    synchronized (lock) {
      System.out.println(name+"持有"+lock+"上2号廁所!");
      for (int i = 0; i < 5; i++) {
        try {
          TimeUnit.SECONDS.sleep(1);
          System.out.println(name+"在廁所呆了"+ i+"s");
        } catch (InterruptedException e) {
          e.printStackTrace();
        }
      }
      System.out.println(name+"從廁所出來!");
    }
  }
}