BlockingQueues和线程访问顺序

Sur*_*eon 5 java queue multithreading

我有一种情况,多个线程将通过调用轮询一个BlockingQueuetake().我想知道的是以下内容:

如果多个线程正在等待队列接收一个项目,那么它们是否会优先按照它们调用的顺序从队列中取出项目,take()或者线程从队列中取出的顺序是否是任意的?

谢谢!

注意:我过去曾为此类事情编写过自己的实现,但我想知道BlockingQueueJava中的实现是否会为我做这个.

Sot*_*lis 5

这取决于实施。

如果您使用 a LinkedBlockingQueue,该take()方法会检查ReentrantLock

public E take() throws InterruptedException {
    E x;
    int c = -1;
    final AtomicInteger count = this.count;
    final ReentrantLock takeLock = this.takeLock;
    takeLock.lockInterruptibly();
    ...
}

// declared as
private final ReentrantLock takeLock = new ReentrantLock(); // no fairness argument, defaults to false
Run Code Online (Sandbox Code Playgroud)

javadoc说

此类的构造函数接受可选的公平参数。当设置为 true 时,在争用情况下,锁倾向于授予等待时间最长的线程访问权限。否则该锁不保证任何特定的访问顺序。使用由许多线程访问的公平锁的程序可能会显示出比使用默认设置的程序更低的总体吞吐量(即更慢;通常慢得多),但在获取锁的时间上具有较小的差异并保证不会出现饥饿。但请注意,锁的公平性并不能保证线程调度的公平性。因此,使用公平锁的许多线程之一可能会连续多次获得公平锁,而其他活动线程没有进展并且当前没有持有该锁。另请注意,不定时的 tryLock 方法不遵守公平性设置。如果锁可用,即使其他线程正在等待,也会成功。