Является ли реализация этого настраиваемого интерфейса потокобезопасной? - PullRequest
2 голосов
/ 01 апреля 2012

У меня много тем, использующих приведенный ниже интерфейс 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 ]

2 голосов
/ 01 апреля 2012

Потокобезопасность - это проблема, возникающая в результате совместного использования состояния данного объекта между различными потоками.

Интерфейсы не имеют значения и поэтому не имеют проблем с безопасностью. С другой стороны, ваши классы, реализующие эти интерфейсы, и, в зависимости от использования, могут столкнуться с проблемами безопасности потоков.

  • Изменяет ли ваш метод какое-либо состояние в классе delcaring?
  • Ваш метод изменяет состояние других объектов, используемых другими потоками?

В коде, которым вы поделились, нет общего состояния между потоками, которые подвергаются риску.

Поскольку вы используете invokeLater(), вы убедитесь, что любые изменения, внесенные в компоненты Swing, выполняются через поток EventDispatch, управляемый Swing.

Мы можем утверждать, что объект, который вы получаете в методе в качестве параметра, также скомпрометирован, но, поскольку вы не меняете его состояние, в настоящий момент он безопасен.

Похоже, ваш код является поточно-ориентированным.

1 голос
/ 01 апреля 2012

Этот конкретный метод является потокобезопасным.

Поскольку runnable является локальной переменной, каждый такой поток будет выделять свою собственную независимую runnable. Поэтому переназначение не может произойти.

И если вы спросите, jTextArea.append является поточно-ориентированным, хотя большая часть Swing - нет.

1 голос
/ 01 апреля 2012

Мне показалось, что это будет выполнено, но не может более одного потока войти в dataChanged () и переназначить исполняемый объект перед SwingUtilities.invokeLater (runnable);обрабатывается?

Между потоками нет ничего общего, что позволило бы такое поведение.Внутри dataChanged вы создаете новый экземпляр Runnable, и каждый поток, который вызывает метод, будет делать то же самое.Учитывая ваш код, ни один поток не сможет изменить один и тот же экземпляр Runnable, поскольку ни один из потоков не использует один и тот же экземпляр.

Другими словами: ваша реализация данного интерфейсапотокобезопасен.

Обновление

Я думаю, что хорошей статьей для чтения по этой теме является Архитектура виртуальной машины Java .Поскольку каждый поток имеет свой собственный стек, вызов метода, включая любые локальные переменные, вычисления и возвращаемые значения (если таковые имеются), будет помещен в стек вызывающего потока.Поскольку потоки не являются общими, никакой другой поток не сможет «увидеть» локальные переменные.Единственный способ, которым поток может «вмешиваться» друг в друга, - это если они что-то делят и в этом случае они ничего не делят.

...