我是否必须同步对 Java 中封装的线程安全数据结构的访问?
假设我有类似的东西(我确实这样做了),
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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
存在线程问题,但不是您想象的那样——您发布的代码几乎肯定是非法的,并且最终会锁定。
Swing 的核心规则之一是只允许一个线程接触“已实现”的组件。 (实现是指在屏幕上或“几乎”在屏幕上)。
这:
在线程内部肯定是错误的——你就是做不到。查看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:
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)..
在这种情况下,不需要外部同步。阅读
BlockingQueue
合同:External synchronization is not necessary in this case. Read the
BlockingQueue
contract:不,没有必要。由于您的 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.您不需要执行此操作,只要
QueBean
中的queue
不发生更改即可。另外,除非您尝试实现某种简单的速率限制,否则您的代码中不需要
wait(500)
。由于队列被阻塞,这是多余的。You don't need to do this, so long as
queue
does not change inQueBean
.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.