Java多线程--生产者消费者模型(Semaphore实现)

时间:2021-10-30 17:42:30

需求

要求:使用2个线程,分别代表:生产者、消费者。让他们并发的去生产、消费产品。生产的总数是不能超过N的。

实现思路

这里我们使用的是使用信号量去控制线程的生产消费,通过释放令牌的形式去控制生产者消费者的上限。使用互斥锁保证每次最多只有一个角色去修改共享变量。来看张图,一图胜千言。
Java多线程--生产者消费者模型(Semaphore实现)

代码实现

代码的注释写的挺详细了,可以仔细阅读一下,若有不懂或者写错的地方欢迎留言。

package model;


import java.util.concurrent.Semaphore;

import static java.lang.System.out;

/**
* Created by lewis on 2017/4/11.
*
* 生产者消费者模型
*
*/

public class ProducerConsumerProblem{

//初始容量
private static final int N = 10;

/***
* full 产品容量
* empty 空余容量
* mutex 读写锁
*/

private static Semaphore full,empty,mutex;
//记录当前的产品数量
private static volatile int count = 0 ;

static {
/**
* full 初始化0个产品
* empty 初始化有N个空余位置放置产品
* mutex 初始化每次最多只有一个线程可以读写
* */

full = new Semaphore(0);
empty = new Semaphore(N);
mutex = new Semaphore(1);
}


public static void main(String []args){
//生产线线程
new Thread(new Producer()).start();
//消费者线程
new Thread(new Consumer()).start();
}

//生产者类
static class Producer implements Runnable{

@Override
public void run() {
while (true){
try {
empty.acquire();//等待空位
mutex.acquire();//等待读写锁
count++;
out.println("生产者生产了一个,还剩:"+count);
mutex.release();//释放读写锁
full.release();//放置产品
//随机休息一段时间,让生产者线程有机会抢占读写锁
Thread.sleep(((int)Math.random())%10);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}

//消费者类
static class Consumer implements Runnable{

@Override
public void run() {
while (true){
try {
full.acquire();//等待产品
mutex.acquire();//等待读写锁
count--;
out.println("消费者消费了一个,还剩:"+count);
mutex.release();//释放读写锁
empty.release();//释放空位
//随机休息一段时间,让消费者线程有机会抢占读写锁
Thread.sleep(((int)Math.random())%10);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}

最后的闲话

其实最近操作系统在教多线程的经典的一些模型,于是打算使用java把这些模型都实现一遍。今天写的是生产者消费者模型。
其实自己开始写这个模型,发现下课后就老师讲的忘了。。。。结果想了好久,未果。于是去翻课件,看了一下伪代码,查了些API才写出来。就这样吧,如若写错欢迎纠错指正。