先贴代码:
苹果工厂:
class AppleFactory{
private LinkedList<Integer> appleBox;
private Integer boxSize;
private AtomicInteger appleCurrentNum;
// 非满锁
private final Semaphore notFull;
// 非空锁
private final Semaphore notEmpty;
// 核心锁
private final Semaphore mutex;
public AppleFactory(LinkedList<Integer> appleBox, Integer boxSize, AtomicInteger appleCurrentNum) {
this.appleBox = appleBox;
this.boxSize = boxSize;
this.appleCurrentNum = appleCurrentNum;
this.mutex = new Semaphore(1); // 初始化核心信号量
this.notFull = new Semaphore(boxSize);// 初始化非满信号量
this.notEmpty = new Semaphore(0);// 初始化非空信号量
}
public void putApple(){
try {
notFull.acquire();// 非满减1
mutex.acquire();// 核心信号加一
int apple = appleCurrentNum.addAndGet(1);
appleBox.addFirst(apple);
System.out.print("生产者,线程:" + Thread.currentThread().getName() + " ] 生产了编号为-" + apple + "-号苹果,当前苹果有:" + appleBox.size() + "个");
System.out.println();
mutex.release(); // 核心恢复信号量
notEmpty.release();// 非空加一
}catch (Exception e){
e.printStackTrace();
}
}
public void takeApple(){
try {
notEmpty.acquire(); // 消费减的是非空信号量
mutex.acquire();
int apple = appleBox.removeFirst();
System.out.print("消费者,线程:" + Thread.currentThread().getName() + " ] 消费了编号为-" + apple + "-号苹果,当前苹果有:" + appleBox.size() + "个");
System.out.println();
mutex.release();
notFull.release();// 消费加的是非满信号量
}catch (Exception e){
e.printStackTrace();
}
}
}
生产者:
class Producer implements Runnable {
private String name;
private AppleFactory appleFactory;
private boolean flag = true;
Producer(String name, AppleFactory appleFactory) {
this.name = name;
this.appleFactory = appleFactory;
}
@Override
public void run() {
while (flag) {
appleFactory.putApple();
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public void stopThread(){
System.out.println("[ " + name +" 生产者 线程 "+ Thread.currentThread().getName() + " ] 停止了");
this.flag = false;
}
}
消费者:
class Consumer implements Runnable {
private String name;
private AppleFactory appleFactory;
private boolean flag = true;
Consumer(String name, AppleFactory appleFactory) {
this.name = name;
this.appleFactory = appleFactory;
}
@Override
public void run() {
while (flag) {
appleFactory.takeApple();
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public void stopThread(){
System.out.println("[ " + name +" 消费者,线程:"+ Thread.currentThread().getName() + " ] 停止了");
this.flag = false;
}
}
测试代码:
public class CAndPTest {
public static void main(String[] args) {
LinkedList<Integer> appleBox = new LinkedList<>();
Integer boxSize = 5;
AtomicInteger initNum = new AtomicInteger(0);
AppleFactory appleFactory = new AppleFactory(appleBox,boxSize,initNum);
ExecutorService executorService = Executors.newFixedThreadPool(6);
List<Producer> producers = new ArrayList<>();
List<Consumer> consumers = new ArrayList<>();
for (int i = 0 ; i < 3 ; i++){
Producer producer = new Producer("P_" + (i + 1),appleFactory);
producers.add(producer);
Consumer consumer = new Consumer("C_" + (i + 1),appleFactory);
consumers.add(consumer);
executorService.submit(producer);
executorService.submit(consumer);
}
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
for (int i = 0 ; i < 3 ; i++){
producers.get(i).stopThread();
consumers.get(i).stopThread();
}
executorService.shutdown();
}
}
信号量原理:
信号量创建的时候会有一个初始的值,假设为1。每一个acquire的时候就减1,release就加一,如果acquire的时候减一如果是小于等于零的话,就等待,如果是大于零的话就等待。