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+"從廁所出來!");
}
}
}