Написание правильного многопоточного кода сложно, и нет волшебной формулы или набора шагов, которые доставят вас туда. Но есть некоторые рекомендации, которыми вы можете следовать.
Лично я бы не начал писать код для одной потоковой среды, а затем преобразовал ее в многопоточную. Хороший многопоточный код разработан с многопоточным разумом с самого начала. Атомарность полей - это всего лишь один элемент параллельного кода.
Вы должны решить, какие области кода должны быть многопоточными (в многопоточном приложении, как правило, не все должно быть потокобезопасным). Затем вам нужно спроектировать, как эти разделы будут потокобезопасными. Способы создания одной области потокобезопасности кода могут быть разными, чем другие области. Например, важно понимать, будет ли большой объем чтения или записи важным и может повлиять на типы блокировок, которые вы используете для защиты данных.
Неизменимость также является ключевым элементом потокобезопасного кода. Когда элементы неизменяемы (т. Е. Не могут быть изменены), вам не нужно беспокоиться о том, что несколько потоков изменяют их, поскольку они не могут быть изменены. Это может значительно упростить проблемы безопасности потоков и позволить вам сосредоточиться на том, где у вас будет несколько считывателей и писателей.
Понимание деталей параллелизма в Java (и деталей модели памяти Java) очень важно. Если вы еще не знакомы с этими понятиями, я рекомендую прочитать Java Concurrency In Practice http://www.javaconcurrencyinpractice.com/.
+1 для неизменности. Минимизация записываемого состояния уменьшает многие проблемы параллелизма. – ide