【问题标题】:Synchronize on BlockedQueue在 BlockedQueue 上同步
【发布时间】:2010-12-07 10:52:03
【问题描述】:

我有一段正在审查的代码(使用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 时,它抱怨 -

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

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

此方法调用 Object.notify() 或 Object.notifyAll() 没有明显 锁定对象。打电话 notify() 或 notifyAll() 没有锁 举行将导致 IllegalMonitorStateException 是 扔了

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

谢谢。

【问题讨论】:

  • 您的testMethod() 本身毫无意义;这个故事一定有更多内容。事实上,答案是“不同步也不调用 notify()”。
  • 查找并发数据结构的大小无论如何都没有多大意义。
  • ChssPly76,谢谢。 testMethod() 就是这样,用于检查大小,并调用 notify()。 “tackline”,我同意你的看法。

标签: java multithreading concurrency findbugs synchronized


【解决方案1】:

BlockingQueue 是一个 syncronizer 对象 - 根据其状态协调线程的控制流,从而控制生产者/消费者线程的流,因为 takeput 阻塞,直到队列进入所需状态(非空或未满)。

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

【讨论】:

    【解决方案2】:

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

    BlockingQueue 使用内部机制在put() 上阻塞更多元素,或者在poll() 上阻塞,如果没有元素可以使用。你不必关心这个。

    【讨论】:

    【解决方案3】:

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

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

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

    【讨论】:

    • 我要解决的问题是确保 FindBug 不报告任何错误。该代码是并发类和原始同步之间的结合。我想知道最好的实现是什么。正如我所说,我正在“审查”代码,并寻找可能的最佳实现方式。
    • 我很确定您以错误的方式解决您的问题,我只是不确定您要解决什么问题。您可以编辑您的初始帖子以提供完整的解决方案吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-08-26
    • 2014-10-04
    • 2016-01-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多