Java多种方式实现 有界缓冲区下的多个生产者、消费者模型 (Semaphore、while+wait+notifyAll)

/**

  • @Author: Song yang Ji

  • @ProjectName: learn-multiThread

  • @Version 1.0

  • @Description:

*/

class ProducerThread extends Thread {

int rate;

MultiProducerConsumer multiProducerConsumer;

public ProducerThread(int rate, MultiProducerConsumer multiProducerConsumer) {

this.multiProducerConsumer = multiProducerConsumer;

this.rate = rate;

}

@Override

public void run() {

while (true) {

try {

multiProducerConsumer.produce();

} catch (InterruptedException e) {

e.printStackTrace();

}

try {

TimeUnit.SECONDS.sleep(rate);

} catch (InterruptedException e) {

e.printStackTrace();

}

}

}

}

class ConsumerThread extends Thread {

int rate;

MultiProducerConsumer multiProducerConsumer;

public ConsumerThread(int rate,MultiProducerConsumer multiProducerConsumer) {

this.rate = rate;

this.multiProducerConsumer = multiProducerConsumer;

}

@Override

public void run() {

while (true) {

try {

multiProducerConsumer.consume();

} catch (InterruptedException e) {

e.printStackTrace();

}

try {

TimeUnit.SECONDS.sleep(rate);

} catch (InterruptedException e) {

e.printStackTrace();

}

}

}

}

public class MultiProducerConsumer {

// 默认缓冲区的长度

static final int DEFAULT_BUFFER_SIZE = 8;

int bufferSize;

// 缓冲数组

char[] bufferArray;

// 生产者放置产品的位置、消费者获取产品的位置 (如果是 AtomicInteger, 生产者(消费者)自身就不需要互斥了)

int putPos, pollPos;

// 生产者使用缓冲的信号量、消费者消费产品的信号量

Semaphore bufferSemaphore, availableSemaphore;

// 使用二级制信号量实现生产者、消费者各自的互斥锁,(Lock 或者其他锁形式也都是可以的)

Semaphore producerMutex, consumerMutex;

public MultiProducerConsumer() {

this(DEFAULT_BUFFER_SIZE);

}

public MultiProducerConsumer(int bufferSize) {

this.bufferSize = bufferSize;

bufferArray = new char[bufferSize];

bufferSemaphore = new Semaphore(DEFAULT_BUFFER_SIZE);

availableSemaphore = new Semaphore(0);

producerMutex = new Semaphore(1);

consumerMutex = new Semaphore(1);

}

// 生产者生产产品

void produce() throws InterruptedException {

// 若缓冲区已满,则阻塞

bufferSemaphore.acquire();

int pos;

// 原子地获取下一个放置的位置

producerMutex.acquire();

pos = putPos;

putPos = (putPos + 1) % bufferSize; // 循环下移

// 唤醒另一个因互斥而阻塞的生产者

producerMutex.release();

// 执行生产操作 (可能耗时很大)

char c = (char) ((int) ‘A’ + pos);

bufferArray[pos] = c;

System.out.printf(“生产者 %s 放置产品 %c 到 buffer[%d]\n”, Thread.currentThread().getName(), c, pos);

// 唤醒可能的消费者消费

availableSemaphore.release();

写在最后

学习技术是一条慢长而艰苦的道路,不能靠一时激情,也不是熬几天几夜就能学好的,必须养成平时努力学习的习惯。所以:贵在坚持!

最后再分享的一些BATJ等大厂20、21年的面试题,把这些技术点整理成了视频和PDF(实际上比预期多花了不少精力),包含知识脉络 + 诸多细节,由于篇幅有限,上面只是以图片的形式给大家展示一部分。

蚂蚁金服三面直击面试官的Redis三连,Redis面试复习大纲在手,不慌

Mybatis面试专题

蚂蚁金服三面直击面试官的Redis三连,Redis面试复习大纲在手,不慌

MySQL面试专题

蚂蚁金服三面直击面试官的Redis三连,Redis面试复习大纲在手,不慌

并发编程面试专题

题,把这些技术点整理成了视频和PDF(实际上比预期多花了不少精力),包含知识脉络 + 诸多细节,由于篇幅有限,上面只是以图片的形式给大家展示一部分。

[外链图片转存中…(img-BBkYHPHk-1726568708033)]

Mybatis面试专题

[外链图片转存中…(img-WEKlQ88s-1726568708034)]

MySQL面试专题

[外链图片转存中…(img-aRq05WPu-1726568708034)]

并发编程面试专题

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值