这个自定义接口实现是否线程安全

时间:2012-03-31 22:15:40

标签: java interface synchronization thread-safety

我有很多线程使用以下接口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);
}

3 个答案:

答案 0 :(得分:2)

线程安全是一个问题,它源于在不同线程之间共享给定对象的状态。

接口没有任何影响,因此它们没有安全问题。另一方面,实现这些接口的类(取决于用法)可能需要处理线程安全问题。

  • 您的方法是否修改了delcaring类中的任何状态?
  • 您的方法是否修改了与其他线程共享的任何其他对象的状态?

在您共享的代码中,受到攻击的线程之间没有共享状态。

由于您使用的是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不是。