我想以线程安全的方式存储对象列表,同时保持优先级。最初,我开始使用BlockingQueue来实现此目的,因为它是线程安全的,并且能够维护自定义优先级。

我想知道是否需要同步我的方法?我的代码如下:

void addToQueue(SomeObject obj) {
    ... put it on my priority queue
    ... do some logging
}


我注意到,当从多个线程访问addToQueue时,日志记录是按顺序进行的。所以我像这样包装了我的方法:

void addToQueue(SomeObject obj) {
    syncronized(myMutex) {
        ... put it on my priority queue
        ... do some logging
    }
}


这似乎使日志记录井然有序。因此,现在我得出的结论是,如果我要走这条路线,那么不使用BlockingQueue而是使用Set或List自己管理优先级,也许我的代码会更高效。

也许我对BlockingQueue有一些误解。

最佳答案

队列还支持以下操作:在检索元素时等待队列变为非空,并在存储元素时等待队列中的空间变为可用。


这是BlockingQueue的javadoc。如果需要这种阻止行为,则可以使用它,否则不需要。

BlockingQueue不保留任何优先级,严格来说是先进先出。也许您正在使用PriorityBlockingQueue

进入您的伪代码:

void addToQueue(SomeObject obj) {
    ... put it on my priority queue
    ... do some logging
}


该队列是线程安全的,但这仅意味着多个线程可以并发调用put it on my priority queue而没有任何数据损坏。它不保证以下任何一项:


如果有多个线程被阻塞,那么哪个将首先成功
如果thread Xput之前完成thread Y,则thread X还将在logging之前完成thread Y


如果需要所有addToQueue发生而不与其他线程交织,则需要进行同步。请注意,您可以使用队列对象本身:

void addToQueue(SomeObject obj) {
    synchronized (queue) {
        ... put it on my priority queue
        ... do some logging
    }
}

关于java - 我是否需要同步对BlockingQueue(java)的调用?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/19504283/

10-09 01:16