2009-12-05 6 views
2

Это связано с более ранней question я спросил, где ответ был:событие отправки Thread встречает модель памяти Java

Если поле доступ несколько потоков, она должна быть энергозависимой или окончательным, или доступны только с синхронизированными блоками. В противном случае присвоенные значения могут быть не видны другим темам.

Кроме того, все, что манипулирует пикселями на экране, должно выполняться с event dispatch thread, хотя при использовании перерисовки/красок оно обрабатывается прозрачно.

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

Мой вопрос в том, правильно ли это понимание, а также примеры учебных пособий на Sun, например TumbleItem (source)?

ответ

1

Вы знаете, я думаю, что у вас может быть точка здесь. В коде TumbleItem используется worker.isDone(), чтобы узнать, завершена ли работа. Однако я не думаю, что это вызывает полную «синхронизацию».

Мой чтение JDK 1.6 код, который использует SwingWorker.isDone()FutureTask, который в свою очередь использует Sync объект с летучим атрибутом state. Путь выполнения для isDone(), по-видимому, не включает метод или блок synchronized.

Я не являюсь экспертом по новым параллельным классам, но я думаю, что TumbleItem должен в какой-то момент звонить worker.get(), чтобы гарантировать правильную синхронизацию.

EDIT: Я имею в виду использование EDT массива img, который заполняется работником. Тем не менее, также появляется проблема с использованием EDT параметров инициализации, как отмечает @ The Feast.

+0

Я думаю, что если бы этот пример использовал атомные целые числа и т. Д., Это сработало бы. Я не вижу эту проблему, особенно обсуждаемую в любом учебнике (Sun или иначе). – Pool

+1

'volatile' имеет тот же эффект памяти, что и синхронизированный. – irreputable

+0

Но ТОЛЬКО на изменчивой переменной не на всех остальных ... или так я понимаю. –

0

Я не уверен, что вы имеете в виду, что учебник Sun неверен?

Анимация выполняется с помощью таймера поворота. Когда таймер запускается, код выполняется на EDT, что означает, что он соответствует рекомендациям Swing.

Edit:

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

И да, «смещение» технически обновлены в двух различных потоков:

а) поток по умолчанию, когда апплет загружался

б) EDT «когда» запускается анимация.

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

Теперь, когда анимация началась, у нас другая ситуация, так как это значение используется графическим интерфейсом для управления анимацией и поэтому должно быть обновлено только кодом на EDT.

В учебнике говорится: «Компоненты Swing должны создаваться, запрашиваться и обрабатываться в потоке диспетчеризации событий», но мы еще не начали ничего делать с компонентами Swing, поэтому я не думаю, что это проблема, но я не эксперт по теме.

+0

'offset', например, изменен несколькими потоками. Я согласен, что это не нарушает никаких рекомендаций EDT. – Pool

+0

См. Отредактированный ответ для дальнейших комментариев. – camickr

1

обычно:

  1. рабочий поток делает некоторые вычисления и достигает определенных результатов.
  2. он вставляет событие в очереди событий
  3. потока событий извлекает событие и процесс его
  4. в ходе процесса результатов доступа.

надлежащая синхронизация была выполнена на шагах (2) и (3). поэтому результаты на шаге (1) могут быть видны на этапе (4). Подумайте, как реализовать очередь событий, и вы увидите.

1

Вы можете использовать ThreadCheckingRepaintManager, чтобы помочь вам найти, когда нарушаете часть EDT (не прямой ответ на ваш вопрос, но полезный, тем не менее :-).