Что происходит, когда два потока одновременно называют один и тот же статический метод?
Что происходит, когда два потока одновременно называют один и тот же статический метод? Например:
public static String someMethod(){
//some logic, can take about 1 second to process
return new String(result);
}
Первый поток вызывает someMethod().
Второй поток вызывает someMethod() через 0,5 секунды (первый поток по-прежнему обрабатывает данные).
Я знаю, что someMethod() можно синхронизировать. Но что произойдет, если он не синхронизируется?
Ответы
Ответ 1
Это зависит от того, изменяется ли ваш метод вне состояния.
static long i = 0l;
public static String someMethod(){
String accm = "";
for(;i < Integer.MAX_VALUE*20/*Just to make sure word tearing occurs*/; i++)
accm += i
return accm;
}
Вызвать проблемы:
- Длинны не гарантированно устанавливаются атомарно, поэтому их можно "разрывать" (Spec)
-
++
не является атомной операцией. Это точно так же, как {int n = i; i = i + 1; return n}
-
i = i + 1
также не является атомарным, если он изменяется в середине, некоторые значения будут повторяться
- Возврат n может быть устаревшим
Но если i
- локальная переменная, проблем не будет. Пока какое-либо внешнее состояние гарантируется неизменным во время его чтения, никогда не может быть никаких проблем.
Ответ 2
Когда вызывается метод, JVM создает стоп-фрейм для вызова в исполняемом потоке. Этот кадр содержит все локальные переменные, объявленные в методе. В случае любого метода, статического или иного, который не имеет доступа к полям, каждое выполнение выполняется полностью независимо от каждого потока. Если метод использует параметры в своем вычислении, эти параметры также находятся в кадре стека, а несколько вызовов не мешают друг другу.
Ответ 3
Тот факт, что метод статичен, не имеет значения. Они должны задавать вопрос о том, какие переменные состояния обрабатываются данным кодом.
- Если никакие члены какого-либо экземпляра/класса не читаются/не записываются, тогда проблем не должно быть.
- В случае операций записи необходима некоторая синхронизация
- Если есть только чтения, это не обязательно означает, что метод хорошо синхронизирован. Это зависит от того, как записываются данные и по какому потоку. Если, например, код считывает V, который защищен монитором M во время операции записи, тогда чтение V должно также синхронизироваться на том же мониторе.
Ответ 4
Если два оператора выполняются в отдельных потоках, то нет гарантии, что первый поток будет виден во втором потоке, если вы не установили связь между этими двумя операциями после синхронизации someMethod()
с использованием данной стратегии синхронизации, Другими словами, ваша логика может дать неожиданные и непредсказуемые результаты, если вы пишете одну и ту же переменную (ы), а затем читаете из двух потоков одновременно.