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