Подход к поточно-безопасной программе - PullRequest
0 голосов
/ 11 октября 2010

All

Какой должен быть подход к написанию многопоточной программы. Учитывая постановку задачи, моя точка зрения такова:

1> Начало написания кода для однопоточной среды.
2> Подчеркните поля, для которых требуется атомарность, и замените их возможными параллельными классами
3> Подчеркните критическую секцию и заключите их в синхронизированный
4> Выполнить тест для взаимоблокировок

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

Программирование на Java

Ответы [ 5 ]

3 голосов
/ 11 октября 2010

Писать правильный многопоточный код сложно, и нет волшебной формулы или набора шагов, которые помогут вам в этом. Но есть некоторые рекомендации, которым вы можете следовать.

Лично я бы не стал писать код для однопоточной среды, а затем преобразовывать его в многопоточную. Хороший многопоточный код с самого начала разрабатывался с учетом многопоточности. Атомность полей - это всего лишь один элемент параллельного кода.

Вы должны решить, какие области кода должны быть многопоточными (в многопоточных приложениях обычно не все должно быть поточно-ориентированным). Затем вам нужно спроектировать, как эти разделы будут безопасны для потоков. Методы создания одной области кода, безопасной для потоков, могут отличаться от других областей. Например, понимание того, будет ли большое количество чтения против записи, важно и может повлиять на типы блокировок, которые вы используете для защиты данных.

Неизменность также является ключевым элементом многопоточного кода. Когда элементы являются неизменяемыми (то есть не могут быть изменены), вам не нужно беспокоиться о том, что несколько потоков изменят их, так как они не могут быть изменены. Это может значительно упростить вопросы безопасности потоков и позволит вам сосредоточиться на том, где у вас будет несколько устройств чтения и записи данных.

Понимание деталей параллелизма в Java (и деталей модели памяти Java) очень важно. Если вы еще не знакомы с этими концепциями, я рекомендую прочитать «Параллелизм Java на практике» http://www.javaconcurrencyinpractice.com/.

1 голос
/ 11 октября 2010

Купите и прочитайте «Параллелизм Java на практике» Брайана Гетца.

1 голос
/ 11 октября 2010

Поскольку вы спрашивали о «поточной безопасности», а не о параллельной производительности, то ваш подход по сути здравый. Тем не менее, поточно-ориентированная программа, которая использует синхронизацию, вероятно, не масштабируется в среде с несколькими процессорами с любым уровнем конкуренции в вашей структуре / программе.

Лично мне нравится пытаться идентифицировать изменения состояния самого высокого уровня и пытаться придумать, как сделать их атомарными, и сделать так, чтобы изменения состояния переходили из одного неизменного состояния в другое - копирование при записи, если хотите. Тогда фактическая запись может быть либо операцией сравнения и установки атомарной переменной, либо синхронизированным обновлением, либо любой стратегией, которая работает / работает лучше всего (при условии, что она безопасно публикует новое состояние).

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

1 голос
/ 11 октября 2010

Вы должны использовать final и неизменяемые поля везде, где это возможно, любые другие данные, которые вы хотите изменить, добавьте внутрь:

  synchronized (this) {
     // update
  }

И помните, иногда вещитормозит, и если это произойдет, вы не хотите продлевать выполнение программы, используя все возможные способы противодействия ей - вместо этого «быстро проваливайтесь».

0 голосов
/ 11 октября 2010

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

...