Являются ли несинхронизированные статические методы потокобезопасными, если они не изменяют статические переменные класса? - PullRequest
142 голосов
/ 03 марта 2011

Мне было интересно, если у вас есть статический метод, который не синхронизирован, но не изменяет какие-либо статические переменные, это потокобезопасно?А что если метод создаст внутри себя локальные переменные?Например, является ли следующий код потокобезопасным?

public static String[] makeStringArray( String a, String b ){
    return new String[]{ a, b };
}

Так что, если у меня есть два потока, вызывающих этот метод непрерывно и одновременно, один с собаками (скажем, «великий датчанин» и «бычья собака») идругой с кошками (скажем, "персидский" и "сиамский"), я когда-нибудь получу кошек и собак в одном ряду?Или кошки и собаки никогда не будут находиться внутри одного и того же вызова метода в одно и то же время?

Ответы [ 5 ]

206 голосов
/ 03 марта 2011

Этот метод является 100% -ным потокобезопасным, он был бы даже если бы он не был static. Проблема с безопасностью потоков возникает, когда вам нужно обмениваться данными между потоками - вы должны заботиться об атомарности, видимости и т. Д.

Этот метод работает только с параметрами , которые находятся в стеке и ссылками на неизменяемые объекты в куче. Стек по своей природе является локальным для потока , поэтому обмен данными никогда не происходит.

Неизменяемые объекты (в данном случае String) также являются потокобезопасными, поскольку после создания они не могут быть изменены, и все потоки видят одно и то же значение. С другой стороны, если бы метод принимал (изменяемый) Date, у вас могла быть проблема. Два потока могут одновременно изменять один и тот же экземпляр объекта, вызывая состояние гонки и проблемы с видимостью.

28 голосов
/ 03 марта 2011

Метод может быть поточно-небезопасным только при изменении какого-либо общего состояния.Неважно, статично оно или нет.

12 голосов
/ 03 марта 2011

Функция отлично защищена от потоков.

Если вы думаете об этом ... предположите, что случилось бы, если бы это было иначе.У каждой обычной функции были бы проблемы с потоками, если бы они не были синхронизированы, поэтому все функции API в JDK должны были бы быть синхронизированы, потому что они могли бы потенциально вызываться несколькими потоками.И поскольку в большинстве случаев приложение использует какой-то API, многопоточные приложения фактически были бы невозможны.

Это слишком нелепо, чтобы думать об этом, так что только для вас: методы не безопасны, если есть явная причина, почемумогут быть проблемы.Старайтесь всегда думать о том, что если бы в моей функции было несколько потоков, а что, если бы у вас был пошаговый отладчик, и один шаг за другим продвигал бы первый ... затем второй поток ... может быть, второй снова ...будут ли проблемы?Если он найден, он не является поточно-ориентированным.

Обратите внимание, что большинство классов Java 1.5 Collection не являются поточно-ориентированными, за исключением тех, где указано, например, ConcurrentHashMap.

И если вы действительно хотите погрузиться в это, внимательно посмотрите на ключевое слово volatile и ВСЕ его побочные эффекты.Посмотрите на класс Semaphore () и Lock () и их друзей в java.util.Concurrent.Прочитайте все документы API вокруг классов.Также стоит учиться и удовлетворять.

Извините за этот слишком сложный ответ.

1 голос
/ 10 октября 2012

Используйте ключевое слово static с синхронизированными статическими методами для изменения статических данных, разделяемых между потоками. С ключевым словом static все созданные потоки будут бороться за одну версию метода.

Использование ключевого слова volatile вместе с синхронизированными методами экземпляров гарантирует, что каждый поток имеет свою собственную копию общих данных и никакие операции чтения / записи не будут просачиваться между потоками.

0 голосов
/ 22 сентября 2011

Строковые объекты, являющиеся неизменяемыми, являются еще одной причиной вышеописанного потокобезопасного сценария. Вместо этого, если используются изменяемые объекты (скажем, makeMutableArray ..), то безопасность потоков наверняка нарушится.

...