如何在Java多线程中实现信号量概念?生产者消费者

如何在Java多线程中实现信号量概念?生产者消费者,java,objective-c,multithreading,semaphore,Java,Objective C,Multithreading,Semaphore,我有两个线程生产者和消费者。在objective-c语言中,我使用信号量来阻止和释放线程消费者 注意:这与生产者-消费者问题有关,但并非完全相关。在这里,生产者不会等待消费者消费。但消费者将等待生产者生产。在这里,消费者没有持续阅读。只有当制作人让他阅读时,他才阅读。并且只读取一些数据这里不是关于共享内存的问题 Thread Consumer{ while(true) { //Consumer is waiting dispatch_semaphore_wait

我有两个线程生产者和消费者。在objective-c语言中,我使用信号量来阻止和释放线程消费者

注意:这与生产者-消费者问题有关,但并非完全相关。在这里,生产者不会等待消费者消费。但消费者将等待生产者生产。在这里,消费者没有持续阅读。只有当制作人让他阅读时,他才阅读。并且只读取一些数据这里不是关于共享内存的问题

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)