使用Semaphore类实现
package com.huo.HelperClass.demo;
import sun.security.krb5.internal.TGSRep;
import java.util.concurrent.Semaphore;
/**
* @version 1.0
* @Author 作者名
* @Date 2022/9/13 11:26
*/
//使用Semaphore实现水果同步问题
public class FruitDemo {
public static void main(String[] args) {
Semaphore plate = new Semaphore(1, true);
Semaphore apple = new Semaphore(0, true);
Semaphore orange = new Semaphore(0, true);
Thread father = new Thread(()->{
while (true) {
try {
plate.acquire();
System.out.println(Thread.currentThread().getName()+" 放入一个苹果");
Thread.sleep(1000);
apple.release();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
Thread mother = new Thread(()->{
try {
plate.acquire();
System.out.println(Thread.currentThread().getName()+" 放入一个橘子");
Thread.sleep(1000);
orange.release();
} catch (InterruptedException e) {
e.printStackTrace();
}
});
Thread son = new Thread(()->{
while (true) {
try {
apple.acquire();
System.out.println( Thread.currentThread().getName() + " 拿走一个苹果");
Thread.sleep(1000);
plate.release();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
Thread daughter = new Thread(() -> {
while (true) {
try {
orange.acquire();
System.out.println(Thread.currentThread().getName() + " 拿走一个橘子");
Thread.sleep(1000);
plate.release();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
father.setName("father");
mother.setName("mother");
son.setName("son");
daughter.setName("daughter");
father.start();
mother.start();
son.start();
daughter.start();
}
}
使用condition监视器实现
package com.huo.pc.fruitdemo;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
/**
* @version 1.0
* @Author 作者名
* @Date 2022/9/12 21:33
*/
/*
妈妈生产橘子 orange = 0
爸爸生产苹果 apple = 0
儿子只吃苹果
女儿只吃橘子
有一个盘子 一个盘子只能放一个资源 plate = 1
*/
public class FruitDemo {
public static void main(String[] args) {
Fruit fruit = new Fruit();
new Thread(()->{
while (true) {
fruit.motherPut();
}
},"妈妈").start();
new Thread(()->{
while (true) {
fruit.daughterGet();
}
},"女儿").start();
new Thread(()->{
while (true) {
fruit.fatherPut();
}
},"爸爸").start();
new Thread(()->{
while (true) {
fruit.sonGet();
}
},"儿子").start();
}
}
class Fruit {
//初始化资源信号量
private int plate = 1; //表示有一个盘子可以用
private int apple = 0; //表示没有资源可以使用
private int orange = 0;
//锁和监视器
Lock lock = new ReentrantLock();
Condition father = lock.newCondition();
Condition son = lock.newCondition();
Condition mother = lock.newCondition();
Condition daughter = lock.newCondition();
/**
* FatherPut
*/
public void fatherPut(){
lock.lock();
try {
//判断果盘是否为空
while (plate == 0) {
//等待
father.await();
}
plate--;
//放入一个苹果
apple++;
System.out.println(Thread.currentThread().getName() +" 生产了一个苹果");
Thread.sleep(100);
//通知儿子拿苹果
son.signal();
} catch (Exception e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
/**
* sonGet
*/
public void sonGet(){
lock.lock();
try {
//判断苹果是否为空
while (apple == 0) {
//等待
son.await();
}
plate++;
//儿子拿苹果
apple--;
System.out.println(Thread.currentThread().getName() +" 拿走了一个苹果");
Thread.sleep(100);
//通知妈妈生产
mother.signal();
} catch (Exception e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
/**
* motherPut
*/
public void motherPut(){
lock.lock();
try {
//判断果盘是否为空
while (plate == 0) {
mother.await();
}
plate--;
//生产一个橘子
orange++;
System.out.println(Thread.currentThread().getName() +" 生产了一个橘子");
Thread.sleep(100);
//通知女儿拿橘子
daughter.signal();
} catch (Exception e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
/**
* daughterGet
*/
public void daughterGet(){
lock.lock();
try {
//判断橘子是否为空
while (orange == 0) {
//等待
daughter.await();
}
plate++;
//拿走橘子
orange--;
System.out.println(Thread.currentThread().getName() +" 拿走了一个橘子");
Thread.sleep(100);
father.signal();
} catch (Exception e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
}
class ThreadTest{
public static void main(String[] args) {
Da da = new Da();
new Thread(() -> {
da.printA();
}, "A").start();
new Thread(() -> {
da.printC();
}, "C").start();
}
static class Da{
public synchronized void printA(){
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName());
}
public void printC(){
System.out.println(Thread.currentThread().getName());
}
}
}