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+"从厕所出来!");
}
}
}