Нужно ли мне синхронизировать доступ к инкапсулированным потокобезопасным структурам данных в Java?

StackOverflow https://stackoverflow.com/questions/2239200

  •  19-09-2019
  •  | 
  •  

Вопрос

Скажем, у меня есть что-то вроде этого (и у меня есть)

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

Должен ли мой poll() в QueBean быть synchronized или нет?

Это было полезно?

Решение

Внешняя синхронизация в этом случае не требуется.Прочтите BlockingQueue договор:

Реализации BlockingQueue безопасны.Все методы очереди достигают их последствий атомно, используя внутренние замки или другие формы контроля параллелизма.

Другие советы

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

Одно из основных правил Swing заключается в том, что только одному потоку разрешено касаться «реализованных» компонентов.(Реализовано означает «на экране» или «почти» на экране).

Этот:

jResultTextField.setText("got one"); 

Внутри потока наверняка будет ошибка — вы просто не сможете этого сделать.Используйте ignoreLater или ignoreAndWait, чтобы получать обновления экрана в поток AWT.

Кстати, забавно иметь потоки во всем, что расширяет компонент. Видя, что это заставляет меня НЕМЕДЛЕННО искать место конфликта, но это должно с первого взгляда вызвать беспокойство у любого Java-программиста со стажем - я предлагаю вам разделите свои классы и полностью отделите часть, которая управляет вашим графическим интерфейсом (контроллером), от графического интерфейса (представления).

Нет.Нет необходимости.Поскольку ваш poll метод ничего не делает, кроме вызова потокобезопасного метода, вероятность повреждения данных отсутствует.

Вам не нужно этого делать, пока queue не меняется в QueBean.

Кроме того, если вы не пытаетесь реализовать какое-то тривиальное ограничение скорости, вам не нужен wait(500) в вашем коде.Это лишнее, поскольку очередь блокируется.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top