我可以在Java中使用Semaphore实现阻塞队列吗? [英] Can I implement blocking queue using Semaphore in Java?

查看:310
本文介绍了我可以在Java中使用Semaphore实现阻塞队列吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想知道是否可以使用Semaphore来实现阻塞队列?

I wonder if it is possible to use Semaphore to implement blocking queue?

在下面的代码中,我使用一个Semaphore来保护关键部分,还有两个信号量对象跟踪空槽和填充对象的数量。

In the below codes, I use one Semaphore to protect the critical section, and two more Semaphore objects to track the number of empty slots and filled objects.

public class BlockingQueue {
  private List<Object> queue = new LinkedList<Object>();
  private int limit;
  private Semaphore slots; // semaphore for empty slots
  private Semaphore objs;  // semaphore for filled slots
  private Semaphore mutex; // for the critical section
  public BlockingQueue(int limit) {
    this.limit = limit;
    this.slots = new Semaphore(limit); // initial empty slot = capacity
    this.objs = new Semaphore(0);
    this.mutex = new Semaphore(1);
  }
  private void enqueue(Object o) throws InterruptedException {
    slots.acquire();
    mutex.acquire(); // critical section starts
    queue.add(o);
    mutex.release(); // critical section ends
    objs.release();
  }
  private Object dequeue() throws InterruptedException {
    objs.acquire();
    mutex.acquire(); // critical section starts
    Object o = queue.remove(0);
    mutex.release(); // critical section ends
    slots.release();
    return o;
  }
}


推荐答案

添加以前的评论 - 我们可以同意你的代码是有效的(这是一个众所周知的算法),特别是你保护LinkedList是正确的,因为它不是内部线程安全的。

Adding to a previous comment - we can agree your code works (it's a well known algorithm), in particular you're correct in protecting the LinkedList since it's not internally thread safe.

但是,如果将代码与java util实现进行比较 http://grepcode.com/file_/repository.grepcode.com/java/root/jdk/openjdk/8u40-b25/java/util/concurrent /ArrayBlockingQueue.java/?v=source
它可能会提出一些要考虑的要点:

However, if you compare your code to the java util implementation http://grepcode.com/file_/repository.grepcode.com/java/root/jdk/openjdk/8u40-b25/java/util/concurrent/ArrayBlockingQueue.java/?v=source it might bring up some points to consider:


  1. 请谷歌讨论ReentrantLock与Binary Semaphore:他们都创建了一个互斥锁&保护关键部分,但前者更好地描述了您的意图,而且可能更容易进行日常维护。例如,同事程序员不能意外地通过没有获得它的线程释放ReentrantLock

  1. please Google for discussions on "ReentrantLock versus Binary Semaphore": They both create a mutex & protect a critical section, but the former better describes your intentions, plus it might be easier for future maintenance. Eg a fellow programmer can't accidentally release a ReentrantLock by a thread that didn't acquire it

Google讨论信号量与条件变量:两者都是允许你等待某些东西变得可用,但是条件变量可能更通用,而且你可以将所有条件绑定到一个锁(就像java util代码那样)。我认为这对性能有一些小的影响,加上你需要接近未来需求的方式,如中断,超时,崩溃。这不会使您的代码错误,这只是您需要考虑的事情。

Google for discussions on "semaphore versus condition variable" : Both allow you to "wait for something to become available", but condition variable might be more general, plus you can tie all your conditions to a single lock (as the java util code does). I assume this has some minor effect on performance, plus the way you'll need to approach future requirements such as interrupts, timeouts, crashes. This doesn't make your code "wrong", it's just something for you to consider.

这篇关于我可以在Java中使用Semaphore实现阻塞队列吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆