2

我有一个正在审查的代码片段(使用FindBugs)。

public class MyClass{
...
private BlockedQueue q = new LinkedBlockingQueue<MyData>(1000);
private static final batchSize = 1000;

public boolean testMethod(){
    boolean done = false;
    synchronized(q){
       if(q.size == batchSize){
         q.notify();
         done = true;
       }
    }
    return done;

}

当我在这段代码上运行 FindBugs 时,它抱怨 -

此方法对作为 java.util.concurrent 包(或其子类)中的类的实例的对象执行同步。这些类的实例有自己的并发控制机制,这些机制与关键字 synchronized 的使用不同且不兼容。

如果我注释掉同步的代码段synchronized(q){,它会抱怨 -

此方法调用 Object.notify() 或 Object.notifyAll() 而不明显持有对象上的锁。在不持有锁的情况下调用 notify() 或 notifyAll() 将导致抛出 IllegalMonitorStateException

我将如何实现此方法以使其通过 FindBugs 验证?在并发课程的情况下,上述实现是否适用于通知?

谢谢你。

4

3 回答 3

3

notify()与 . 的类一起使用wait()且不应与java.util.concurrent.

BlockingQueue 使用内部机制在put()没有空间容纳更多元素或poll()没有要消耗的元素时阻塞。你不必关心这个。

于 2009-10-16T17:42:41.207 回答
0

第一个错误是说明您不应在 java.util.concurrent 类(如 BlockingQueue)上使用原始同步控件。

通常,这是一种很好的做法,因为他们会为您处理同步。我想有更好的方法来解决您手头的问题。您要解决的实际问题是什么?

第二个错误是由于您必须拥有对象的锁/监视器(通过对其进行同步)才能在其上调用 wait/notify/notifyAll

于 2009-10-16T17:33:45.123 回答
0

BlockingQueue 是一个同步器对象 - 根据其状态协调线程的控制流,从而控制生产者/消费者线程的流,因为在队列进入所需状态(非空或未满)之前获取放置阻塞。

并发编程中的良好实践还假定将等待和通知放在 while 循环中。

于 2009-10-16T18:38:24.723 回答