Определение безопасности потока приведены в Java Concurrency in Practice является:
Класс потокобезопасна, если он ведет себя правильно, когда доступ из нескольких потоков, независимо от планирования или чередования выполнение этих потоков средой выполнения и без дополнительной синхронизации или другой координации со стороны вызывающего кода.
Например, объект java.text.SimpleDateFormat имеет внутреннее изменяемое состояние, которое изменяется, когда вызывается метод, который анализирует или форматирует. Если несколько потоков вызывают методы одного и того же объекта dateformat, есть вероятность, что поток может изменить состояние, необходимое другим потокам, в результате чего результаты, полученные некоторыми потоками, могут быть ошибочными. Возможность иметь внутреннее состояние повреждена, что приводит к плохому результату, что делает этот класс небезопасным.
Существует несколько способов решения этой проблемы. Вы можете иметь каждое место в своем приложении, которое требует, чтобы объект SimpleDateFormat создавал новый экземпляр каждый раз, когда он ему нужен, вы можете сделать ThreadLocal, содержащий объект SimpleDateFormat, чтобы каждый поток вашей программы мог получить доступ к своей собственной копии (так что каждый поток имеет только для его создания), вы можете использовать альтернативу SimpleDateFormat, которая не сохраняет состояние, или вы можете блокировать с помощью synchronized
, так что только один поток за один раз может получить доступ к объекту dateFormat. Блокировка не обязательно является наилучшим подходом, поэтому лучше избегать совместного измененного состояния.
Ключевое слово synchronized
является одним из способов ограничения доступа к методу или блоку кода, чтобы иначе данные, не зависящие от потоков, не повреждались. Это ключевое слово защищает метод или блок, требуя, чтобы поток получал эксклюзивный доступ к определенной блокировке (экземпляр объекта, если синхронизирован, находится в методе экземпляра или экземпляр класса, если синхронизирован по статическому методу или указанному блокировка при использовании синхронизированного блока), прежде чем он сможет ввести метод или блок, обеспечивая при этом видимость памяти, чтобы потоки не отображали устаревшие данные.
@jtahlborn: «Все» - это * путь * завышение его. : P Требуется больше, чем просто синхронизация; требуется * согласованная * синхронизация. Если два потока, которые взаимодействуют с одним и тем же материалом, не синхронизируются с одним и тем же блокиром/монитором/мьютеком/независимо, то у вас есть много таких же проблем, как если бы они вообще не синхронизировались. – cHao
@cHao - я обобщал. да, просто сбрасывая синхронизацию вокруг не делает ваш код потокобезопасным. как насчет «синхронизации является механизмом для обеспечения безопасности кода, но не все поточно-безопасные коды используют синхронизацию». – jtahlborn
, если код синхронизирован, то как он будет использоваться несколькими потоками (в соответствии с потоками)? – Nayak