我必须同步访问Java中封装的线程安全数据结构吗?

我必须同步访问Java中封装的线程安全数据结构吗?,java,concurrency,synchronized,Java,Concurrency,Synchronized,假设我有这样的东西(我有) 其中一些在自己的线程上运行 class ConsumerBean extends JPanel implements Runnable{ private QueBean queBean; public synchronized run(){ while (true) { Object result = queBean.poll(); if (result != null) {

假设我有这样的东西(我有)

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

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()
是否应同步?

否。不需要。由于您的
poll
方法除了调用线程安全方法外,什么都不做,因此不存在数据损坏的可能性。

只要
queue
queebean
中没有更改,您就不需要这样做


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

存在线程问题,但不是您认为的问题——您发布的代码几乎肯定是非法的,最终会被锁定

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

这:

在一个线程中,肯定是错误的——你就是做不到。查看invokeLater或invokeAndWait,将屏幕更新添加到AWT线程中


顺便说一句——在任何扩展组件的地方都有线程感觉很有趣——看到这一点,我会立即搜索冲突的位置,但这会让任何长期的Java程序员一眼就感到不安——我建议您将一些类拆分,并将驱动GUI(控制器)的部分与GUI(视图)完全分离..

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

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


还有什么其他用途
queBean
?例如,是什么增加了内容?@T.J.Crowder queBean有自己的线程,可以将内容随机添加到队列中。我正在做一些琐碎的速率限制;)你说的非法是什么意思?它当然可以编译和运行。(textField方法调用在另一个私有方法中)
java.awt.EventQueue.invokeLater
是您想要的。因此,如果我在EventQueue上启动GUI更新,它会更安全?@Bedwyr:GUI更新(或任何导致它的事情,例如更新模型)必须在EDT上发生,并且没有其他线程,否则您将面临未定义行为的风险。所以,“更安全”是一个严重的轻描淡写的说法非法我的意思是,它将工作很长一段时间,但偶尔您会看到GUI上出现故障或GUI将挂起。最终,您将开始看到更严重的问题——过了一段时间,似乎对GUI布局的每一次修改都会以不可预测的方式破坏某些东西。每当您修改屏幕上的任何内容以修复它时,请使用invokeLater或invokeAndWait。
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);
        }
    }
}
jResultTextField.setText("got one");