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

发布于 2024-08-20 14:17:40 字数 659 浏览 4 评论 0原文

假设我有类似的东西(我确实这样做了),

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

Say I have something like this (and I do)

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

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

with some of these that run on their own threads

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);
        }
    }
}

Should my poll() in the QueBean be synchronized or not?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

许久 2024-08-27 14:17:40

存在线程问题,但不是您想象的那样——您发布的代码几乎肯定是非法的,并且最终会锁定。

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

这:

jResultTextField.setText("got one"); 

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

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

There is a threading problem, but not the one you think--The code you posted is almost certainly illegal and will eventually lock up.

One of the core rules of Swing is that only one thread is allowed to touch "realized" components. (Realized means on-screen or "almost" on-screen).

This:

jResultTextField.setText("got one"); 

Inside a thread is pretty sure to be wrong--you just can't do it. Check out invokeLater or invokeAndWait to get your screen updates onto your AWT thread.

By the way--it feels funny having threads in anything that extends a component--seeing that lead me to IMMEDIATELY search for where the conflict was, but it should make any long-time Java programmer uneasy at a glance--I suggest you split up your classes some and completely separate the part that drives your GUI (Controller) from the GUI (View)..

青柠芒果 2024-08-27 14:17:40

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

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

External synchronization is not necessary in this case. Read the BlockingQueue contract:

BlockingQueue implementations are
thread-safe. All queuing methods
achieve their effects atomically using
internal locks or other forms of
concurrency control.

镜花水月 2024-08-27 14:17:40

不,没有必要。由于您的 poll 方法除了调用线程安全方法之外不执行任何操作,因此不存在数据损坏的可能性。

No. There is no need. Since your poll method does nothing except call a thread-safe method, there is no possibility of data corruption.

凉世弥音 2024-08-27 14:17:40

您不需要执行此操作,只要 QueBean 中的 queue 不发生更改即可。

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

You don't need to do this, so long as queue does not change in QueBean.

Also, unless you're trying to implement some kind of trivial rate-limitng, you don't need the wait(500) in your code. It's superfluous due to the queue being blocking.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文