我正在审核的代码片段(使用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(q){
,它就会抱怨 -
此方法调用Object.notify()或 Object.notifyAll()没有明显的 持有锁在物体上。调用 没有锁的notify()或notifyAll() 举行将导致 IllegalMonitorStateException正在 抛出
我如何实现此方法以便它传递FindBugs验证?对于并发类,上述实现是否适用于通知?
谢谢。
答案 0 :(得分:2)
notify()
与wait()
一起使用,不应与java.util.concurrent
类一起使用。
如果没有可用于更多元素的空间,则BlockingQueue使用内部机制阻止put()
;如果没有要使用的元素,则阻塞poll()
。你不必关心这个。
答案 1 :(得分:0)
第一个错误是声明你不应该对java.util.concurrent类使用原始同步控件(比如BlockingQueue)。
通常,这是一种很好的做法,因为它们会为您处理同步。我想有一种更好的方法来解决你手头的问题。你想要解决的实际问题是什么?
第二个错误是由于你必须拥有一个对象的锁定/监视器(通过同步它)来调用wait / notify / notifyAll
答案 2 :(得分:0)
BlockingQueue是一个 syncronizer 对象 - 根据线程的状态协调线程的控制流,从而控制生产者/消费者线程的流量,因为取和 put < / strong>阻塞,直到队列进入所需状态(非空或未满)。
并发编程中的良好实践也假设wait和notify位于while循环中。