最近在复习操作系统的时候,看到一个使用信号量的例子。
然后自己用java实现了一下,
本来还想用swing可视化一下的,后来想想就算了。。。
题目
- 有一个仓库存放两种零件A和B,最大库容各为 m 个。
- 有一个车间不断地取A和B进行装配, 每次各取一个。
- 有两组供应商不断供应A和B (每次一个),
- 为保证齐套和合理库存,当某种零件的数量比另一种的数量超过n (n < m) 个时,
- 暂停对数量大的零件的进货,集中补齐少的零件。
- 初始时仓库是空的。
- m = 10, n = 3
代码及其注释已经很详细了。
package com.jsy.juc.thread_util;
import java.util.concurrent.Semaphore;
import java.util.concurrent.TimeUnit;
/**
* @Author: Song yang Ji
* @ProjectName: learn-multiThread
* @Version 1.0
* @Description: 题目:有一个仓库存放两种零件A和B,最大库容各为 m 个。
* 有一个车间不断地取A和B进行装配, 每次各取一个。
* 有两组供应商不断供应A和B (每次一个),
* 为保证齐套和合理库存,当某种零件的数量比另一种的数量超过n (n < m) 个时,
* 暂停对数量大的零件的进货,集中补齐少的零件。
* 初始时仓库是空的。
* m = 10, n = 3
* 仅使用信号量,不允许用synchronized、Lock,完成并发控制
*/
/**
* 本题有6个约束关系,并记信号量分别为:
* a >= 0, availASem = 0
* b >= 0, availBSem = 0
* a <= m, capacityASem = m
* b <= m, capacityBSem= m
* b - a <= n, baSem = n
* a - b <= n, abSem = n
*/
public class SemaphoreExample {
static final int M = 10, N = 3;
// 6个信号量
// 控制车间获取A、B的信号量
static Semaphore availASem = new Semaphore(0), availBSem = new Semaphore(0);
// 控制供应商提供零件的信号量
static Semaphore capacityASem = new Semaphore(M), capacityBSem = new Semaphore(M);
// 控制A与B差值的信号量
static Semaphore baSem = new Semaphore(N), abSem = new Semaphore(N);
// 0-1信号量,模拟互斥锁
static Semaphore mutex = new Semaphore(1);
static void consumer() {
do {
try {
availASem.acquire();
availBSem.acquire();
mutex.acquire();
// 注意这一步是不影响 A、B 差值
System.out.println("生成车间取出零件 A、B 进行组装");
TimeUnit.SECONDS.sleep(1);
mutex.release();
capacityASem.release();
capacityBSem.release();
} catch (InterruptedException e) {
e.printStackTrace();
}
} while (true);
}
static void providerA() {
do {
try {
capacityASem.acquire();
abSem.acquire();
mutex.acquire();
System.out.println("供应商提供零件 A 放入仓库");
TimeUnit.SECONDS.sleep(1);
mutex.release();
availASem.release();
baSem.release();
} catch (InterruptedException e) {
e.printStackTrace();
}
} while (true);
}
static void providerB() {
do {
try {
capacityBSem.acquire();
baSem.acquire();
mutex.acquire();
System.out.println("供应商提供零件 B 放入仓库");
TimeUnit.SECONDS.sleep(1);
mutex.release();
availBSem.release();
abSem.release();
} catch (InterruptedException e) {
e.printStackTrace();
}
} while (true);
}
public static void main(String[] args) {
new Thread(SemaphoreExample::consumer).start();
new Thread(SemaphoreExample::providerA).start();
new Thread(SemaphoreExample::providerB).start();
}
}