【问题标题】:Do I have to synchronize access to encapsulated thread-safe data structures in Java?我是否必须同步对 Java 中封装的线程安全数据结构的访问?
【发布时间】:2010-02-10 18:03:27
【问题描述】:

说我有这样的事情(我确实有)

class QueBean extends JPanel {
    private Queue queue = new LinkedBlockingQueue();

    public Object poll(){
        return queue.poll();
    }
}

其中一些在自己的线程上运行

class ConsumerBean extends JPanel implements Runnable{
    private QueBean queBean;

    public synchronized run(){
        while (true) {
           Object result =  queBean.poll();
           if (result != null) {
              jResultTextField.setText("got one");  
           }
           wait(500);
        }
    }
}

我在QueBean 中的poll() 是否应该是synchronized

【问题讨论】:

  • queBean 还有什么用途?例如,什么增加了它?
  • @T.J. Crowder queBean 有它自己的线程,可以随机添加东西到队列中。

标签: java concurrency synchronized


【解决方案1】:

有一个线程问题,但不是你想的那样——你发布的代码几乎肯定是非法的,最终会被锁定。

Swing 的核心规则之一是只允许一个线程接触“已实现”的组件。 (实现意味着在屏幕上或“几乎”在屏幕上)。

这个:

jResultTextField.setText("got one"); 

线程内部肯定是错误的——你就是做不到。查看 invokeLater 或 invokeAndWait 以将屏幕更新更新到 AWT 线程。

顺便说一句——在任何扩展组件的东西中都有线程感觉很有趣——看到这导致我立即搜索冲突的位置,但它应该会让任何长期使用 Java 程序员的人一眼就感到不安——我建议您将您的类分开一些,并将驱动您的 GUI(控制器)的部分与 GUI(视图)完全分开。

【讨论】:

  • 非法是什么意思?它当然可以编译和运行。 (textField方法调用在另一个私有方法中)
  • java.awt.EventQueue.invokeLater 是你想要的。
  • 那么如果我在 EventQueue 上触发 GUI 更新会更安全吗?
  • @Bedwyr:GUI 更新(或导致它的任何事情,例如更新模型)必须在 EDT 上发生,并且不能在其他线程上发生,否则您将面临未定义行为的风险。所以,“更安全”是一个严重的轻描淡写。 :-)
  • 非法我的意思是它可以工作很长时间,但偶尔你会在 GUI 上看到故障或 GUI 会挂起。最终,您将开始看到更严重的问题——一段时间后,似乎对您的 GUI 布局的每一次修改都会以不可预知的方式破坏某些东西。每当您修改屏幕上的任何内容以修复它时,请使用 invokeLater 或 invokeAndWait。
【解决方案2】:

在这种情况下不需要外部同步。阅读BlockingQueue 合约:

BlockingQueue 的实现是 线程安全。所有排队方法 使用原子地实现它们的效果 内部锁或其他形式的 并发控制。

【讨论】:

    【解决方案3】:

    没有。没有必要。由于您的 poll 方法除了调用线程安全方法之外什么都不做,因此不会有数据损坏的可能性。

    【讨论】:

      【解决方案4】:

      您不需要这样做,只要queueQueBean 中不变。

      此外,除非您尝试实现某种微不足道的速率限制,否则您的代码中不需要 wait(500)。由于队列被阻塞,这是多余的。

      【讨论】:

      • 我正在做一些微不足道的限速 ;)
      猜你喜欢
      • 2013-02-15
      • 2021-06-14
      • 1970-01-01
      • 1970-01-01
      • 2011-09-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多