如何在Java多线程中实现信号量概念?生产者消费者
我有两个线程生产者和消费者。在objective-c语言中,我使用信号量来阻止和释放线程消费者 注意:这与生产者-消费者问题有关,但并非完全相关。在这里,生产者不会等待消费者消费。但消费者将等待生产者生产。在这里,消费者没有持续阅读。只有当制作人让他阅读时,他才阅读。并且只读取一些数据这里不是关于共享内存的问题如何在Java多线程中实现信号量概念?生产者消费者,java,objective-c,multithreading,semaphore,Java,Objective C,Multithreading,Semaphore,我有两个线程生产者和消费者。在objective-c语言中,我使用信号量来阻止和释放线程消费者 注意:这与生产者-消费者问题有关,但并非完全相关。在这里,生产者不会等待消费者消费。但消费者将等待生产者生产。在这里,消费者没有持续阅读。只有当制作人让他阅读时,他才阅读。并且只读取一些数据这里不是关于共享内存的问题 Thread Consumer{ while(true) { //Consumer is waiting dispatch_semaphore_wait
Thread Consumer{
while(true) {
//Consumer is waiting
dispatch_semaphore_wait(semaphoreVariable, DISPATCH_TIME_FOREVER);
//Copies the data and then goes to wait.
}
}
Thread Producer{
while(true){
//write to buffer
//Continuously writes to buffer. No Waiting.
//After writing Some Blocks asks consumer to consume
dispatch_semaphore_signal(semaPhoreBlock);
}
}
像这样,信号量用于连续地阻塞和释放使用者线程
如何在JAVA中实现这种机制?非常感谢任何帮助。Java解决方案是:不要使用/实现信号量这样的“低级”概念 相反,使用Java平台提供的许多抽象之一,例如 这非常简单:当您有两个线程时,一个线程将内容推送到队列中;另一个读卡器线程使用
take()
方法来获取内容
其中:take()
blocks!因此,您根本不需要担心“手动”发送信号。一个线程写入,读取器坐着等待,直到内容可用。意思是:你确实不需要明确地告诉读者“开始阅读”——这是在封面下隐含地发生的
从这个意义上说:真正的答案是研究Java必须提供的服务,而不是自己尝试构建抽象。Oracle的并发性是一个很好的起点。不要认为来自语言A的解决方案必须在另一种语言中以相同的方式“工作”。在Java中,编写器在使用BlockingQueue时不需要向读取器发出信号。因此,不要强制执行来自另一种语言的概念,从而使你的生活变得更加复杂 Java解决方案是:不要使用/实现信号量这样的“低级”概念 相反,使用Java平台提供的许多抽象之一,例如 这非常简单:当您有两个线程时,一个线程将内容推送到队列中;另一个读卡器线程使用
take()
方法来获取内容
其中:take()
blocks!因此,您根本不需要担心“手动”发送信号。一个线程写入,读取器坐着等待,直到内容可用。意思是:你确实不需要明确地告诉读者“开始阅读”——这是在封面下隐含地发生的
从这个意义上说:真正的答案是研究Java必须提供的服务,而不是自己尝试构建抽象。Oracle的并发性是一个很好的起点。不要认为来自语言A的解决方案必须在另一种语言中以相同的方式“工作”。在Java中,编写器在使用BlockingQueue时不需要向读取器发出信号。因此,不要强制执行来自另一种语言的概念,从而使你的生活变得更加复杂 我会用“屏障”来解决这个协调问题 消费者不会持续阅读。当制作人通知他这样做(通过重置屏障)时,它只读取一批作品 我还添加了一些等待生产者的内容(因此,如果消费者速度太慢,队列不会溢出),但生产者只会在生产一批作品后,没有消费者准备好消费它时才会等待 见下文:
import java.util.Queue;
import java.util.Random;
import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.Callable;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.CyclicBarrier;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import java.util.stream.IntStream;
public class BarrierExample {
public static final int BATCH_SIZE = 10;
public static void main(String[] args) throws InterruptedException {
BarrierExample barrierExample = new BarrierExample();
barrierExample.doTheWork();
}
private void doTheWork() throws InterruptedException {
Queue<String> queue = new ConcurrentLinkedQueue();
CyclicBarrier barrier = new CyclicBarrier(2);
ExecutorService executorService = Executors.newFixedThreadPool(2);
executorService.submit(new Producer(BATCH_SIZE, queue, barrier));
executorService.submit(new Consumer(BATCH_SIZE, queue, barrier));
Thread.sleep(4000);
System.out.println("main program: trying to shutdown executor service");
executorService.shutdownNow();
executorService.awaitTermination(5, TimeUnit.SECONDS);
}
}
class Producer implements Callable<Void> {
private final int batchSize;
private Queue queue;
private CyclicBarrier barrier;
private Random random = new Random();
public Producer(int batchSize, Queue queue, CyclicBarrier barrier) {
this.batchSize = batchSize;
this.queue = queue;
this.barrier = barrier;
}
@Override
public Void call() {
while (true) {
IntStream.range(1, batchSize).forEach(i -> queue.add(String.valueOf(random.ints(1, 10).findFirst().getAsInt())));
System.out.println("producer: batch size was added to queue.");
while (barrier.getNumberWaiting() < 1) {
try {
System.out.println("producer: nobody is waiting on barrier. going to sleep now");
Thread.sleep(2000);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
if (Thread.currentThread().isInterrupted()) {
break;
}
}
System.out.println("producer: consumer was waiting on barrier. reseting the barrier now");
barrier.reset();
if (Thread.currentThread().isInterrupted()) {
System.out.println("producer is ending now!");
break;
}
}
return null;
}
}
class Consumer implements Callable<Void> {
private final int batchSize;
private Queue queue;
private CyclicBarrier barrier;
public Consumer(int batchSize, Queue queue, CyclicBarrier barrier) {
this.batchSize = batchSize;
this.queue = queue;
this.barrier = barrier;
}
@Override
public Void call() {
while (true) {
boolean barrierIsBroken = false;
try {
System.out.println("consumer: waiting on barrier");
barrier.await();
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
} catch (BrokenBarrierException e) {
System.out.println("consumer: barrier is broken!!");
barrierIsBroken = true;
}
if (barrierIsBroken) {
System.out.println("consumer: consuming batch");
IntStream.range(1, batchSize).forEach(i -> System.out.println(queue.remove()));
System.out.println("consumer: queue size:" + queue.size());
}
try {
System.out.println("consumer: going to sleep");
Thread.sleep(2000);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
if (Thread.currentThread().isInterrupted()) {
System.out.println("consumer is ending now!");
break;
}
}
return null;
}
}
import java.util.Queue;
导入java.util.Random;
导入java.util.concurrent.BrokenBarrierException;
导入java.util.concurrent.Callable;
导入java.util.concurrent.ConcurrentLinkedQueue;
导入java.util.concurrent.CyclicBarrier;
导入java.util.concurrent.ExecutorService;
导入java.util.concurrent.Executors;
导入java.util.concurrent.TimeUnit;
导入java.util.stream.IntStream;
公共类障碍物示例{
公共静态最终整数批大小=10;
公共静态void main(字符串[]args)引发InterruptedException{
BarrierExample BarrierExample=新的BarrierExample();
barrierExample.doTheWork();
}
private void doTheWork()引发InterruptedException{
Queue Queue=新的ConcurrentLinkedQueue();
CyclicBarrier屏障=新CyclicBarrier(2);
ExecutorService ExecutorService=Executors.newFixedThreadPool(2);
提交(新生产商(批量大小、队列、屏障));
提交(新消费者(批量大小、队列、屏障));
睡眠(4000);
System.out.println(“主程序:尝试关闭executor服务”);
executorService.shutdownNow();
执行器服务。等待终止(5,时间单位。秒);
}
}
类生产者实现了可调用{
私有最终整数批量大小;
专用队列;
私人自行车运载障碍;
私有随机=新随机();
公共生产者(int batchSize、队列、CyclicBarrier屏障){
this.batchSize=batchSize;
this.queue=队列;
这个障碍=障碍;
}
@凌驾
公开作废通知(){
while(true){
IntStream.range(1,batchSize).forEach(i->queue.add(String.valueOf(random.ints(1,10.findFirst().getAsInt()));
System.out.println(“生产者:批量大小已添加到队列。”);
while(barrier.getNumberWaiting()<1){
试一试{
System.out.println(“制作人:没有人在等待屏障。现在就去睡觉”);
《睡眠》(2000年);
}捕捉(中断异常e){
Thread.currentThread().interrupt();
}
if(Thread.curr)