我有很多线程使用以下接口ServerMessage
如果许多线程同时调用dataChanged()
im
使用SwingUtilities.invokeLater
来解雇工作。
我的感觉是这种情况会持续但不能再多了
一个帖子输入dataChanged()
并重新分配runnable
在处理SwingUtilities.invokeLater(runnable);
之前?
也许我应该像这样锁定runnable
。
synchronized (runnable) {
work...
}
当下一个线程进入时,sO
也不会改变呢?
我的界面被许多线程使用
public interface ServerMessage{
public void dataChanged(ServerEventObjects se);
public void logChanged(String txt);
}
这是界面方法
@Override
public void dataChanged(final ServerEventObjects sO) {
Runnable runnable = new Runnable() {
public void run(){
// create new ServerEventObject to avoid making changes to original.
// could clone() it but mongoDb didn't like that
ServerEventObject serverEventObject = new ServerEventObject();
serverEventObject.eventUuid = sO.eventUuid;
serverEventObject.eventUuid = sO.message;
jTextAreaLog.append(serverEventObject.message +"\n" );
JTableModel.add(serverEventObject)
}
};
SwingUtilities.invokeLater(runnable);
}
答案 0 :(得分:2)
线程安全是一个问题,它源于在不同线程之间共享给定对象的状态。
接口没有任何影响,因此它们没有安全问题。另一方面,实现这些接口的类(取决于用法)可能需要处理线程安全问题。
在您共享的代码中,受到攻击的线程之间没有共享状态。
由于您使用的是invokeLater()
,因此您确保对Swing组件所做的任何更改都是通过Swing控制的EventDispatch
线程完成的。
我们可以争辩说,你在方法中作为参数收到的对象也会受到损害,但由于你没有改变它的状态,所以暂时它是安全的。
因此,您的代码似乎是线程安全的。
答案 1 :(得分:1)
我的感觉是,这种情况会持续但不会更多 一个线程进入dataChanged()并在SwingUtilities.invokeLater(runnable)之前重新分配runnable;是处理?
线程之间没有任何共享可以允许这种行为。在dataChanged
内部,您创建一个新的Runnable
实例,并且调用该方法的每个线程都会执行相同的操作。鉴于您的代码,没有线程能够修改相同的Runnable
实例,因为没有线程共享同一个实例。
换句话说:给定接口的您的实现是线程安全的。
我认为阅读该主题的好文章是The Architecture of the Java Virtual Machine。由于每个线程都有自己的堆栈,因此方法调用(包括任何局部变量,计算和返回值(如果有))将被推送到调用线程的堆栈中。由于线程堆栈不是共享的,因此没有其他线程能够“看到”局部变量。线程可以“干扰”彼此的唯一方式是,如果他们共享某些内容,并且在这种情况下,他们就不会共享任何内容。
答案 2 :(得分:1)
这种特殊方法是线程安全的。
因为runnable
是一个局部变量,所以每个这样的线程都会分配自己独立的runnable
。因此,不能重新分配。
如果你问,jTextArea.append
是线程安全的,虽然大多数Swing不是。