Я изучаю параллельное программирование в java и пишу симуляцию для Game of Life.Многопоточная Java-программа для игры в жизни Конвея - соперничество в пограничных ячейках
Вот что я имею в виду:
- Использование ИНТ [] [] для сохранения состояния ячеек
- разбивают ИНТ [] [] в т сегментов и использовать т рабочие потоки
- Т-потоки будут считывать из своего сегмента, вычислять новые значения для всех ячеек в их сегменте и обновлять ячейки.
- Как только они закончили расчет, они ждут у барьера для других рабочих, чтобы закончить
- Когда барьер пересек, основной поток обновит пользовательский интерфейс.
- рабочие приступают к вычислению следующего состояния.
Теперь на общих границах сегментов будет обсуждаться. Если поток переполнил состояние пограничной ячейки до того, как ее сосед прочитал предыдущее значение, подсчет соседа будет неправильным.
Какие у меня варианты?
- Использовать вызываемый вместо runnable и иметь рабочие потоки, возвращать новое значение (вместо обновления самих сегментов). Основной поток может обновить матрицу после пересечения барьера. Этот параметр включает копирование результатов, возвращаемых рабочими потоками в матрицу.
- Используйте два барьера. Рабочая нить делает копию пограничных ячеек из сегментов своих соседей и ждет первого барьера. Как только этот барьер передан, они переходят к вычислению следующих состояний и обновляют сегменты на месте. Затем они ждут второго барьера. основной поток обновляет пользовательский интерфейс.
Мой вопрос, есть ли другой способ иметь дело с утверждением на пограничных клетках , что не включает в себя копирование данных или является более эффективным, что вышеупомянутые два варианта? Может быть, использовать ReaderWriterLock, изменчивую переменную или другой механизм синхронизации?
ОБНОВЛЕНИЕ: Пока double buffering solution by Peter является самым чистым. Но у меня есть вопрос. Поскольку два массива являются общими данными, и мы не используем какую-либо синхронизацию (синхронизированный доступ или изменчивую переменную), не создаст ли она проблему видимости? Могут ли несколько ЦП кэшировать значения массива и обновлять только часть массива с каждой итерацией? Затем потоки получат устаревшие значения для пограничных ячеек. Это возможно? Если нет, то почему. Если да, то как мне его решить? Кажется declaring two arrays volatile will not make their individual elements volatile.
что-то рассмотреть, используя AtomicInt вместо обычного int –
Advantage? Не будет ли это чрезмерной синхронизацией? – Helen
Зачем вам нужно использовать int, не было бы логичнее и эффективнее хранить с помощью booleans? – Pool