Являются ли несинхронизированные статические методы потокобезопасными, если они не изменяют статические переменные класса?



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



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


Итак, если у меня есть два потока, вызывающие метод ths непрерывно и одновременно, один с собаками (скажем, "Great dane" и "bull dog"), а другой с кошками (скажем, "персидский" и "Сиамский"), я когда-нибудь заводят кошек и собак в одном массиве? Или кошки и собаки никогда не будут находиться внутри одного и того же вызова метода в одно и то же время?

583   5  

5 ответов:

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

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

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

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

функция совершенно потокобезопасна.

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

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

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

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

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

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

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

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

Comments

    Ничего не найдено.