Являются ли параметры метода потоками безопасными в Java?
Class Shared{
public void sharedMethod(Object o){
//does something to Object
}
}
//this is how threads call the shared method
run(){
sharedInstance.sharedMethod(someObject);
}
Теперь o
передается как параметр метода. И тот же метод вызывается несколькими потоками параллельно. Можем ли мы с уверенностью сказать, что этот код является потокобезопасным?
Существует два сценария:
- Если
someObject
делится между потоками
- Если каждый поток имеет свою собственную копию
someObject
Ответы
Ответ 1
Нет, вы не можете этого сказать. Параметры метода локальны для потоков, то есть каждая имеет свою собственную копию ссылочной переменной o
, но если вы вызовете этот метод с тем же объектом из нескольких потоков, тогда аргумент будет передан между ними (помните, что Java - это пропуск -по-значение). В этом случае вам необходимо предоставить явную синхронизацию, чтобы избежать проблем.
Ответ 2
Если вы вызываете тот же метод в нескольких потоках и передаете ему тот же объект, этот объект абсолютно небезопасен.
Ответ 3
Когда вы создаете поток, у него будет свой собственный стек (метод и локальные переменные).
Два потока будут иметь два стека, а один поток никогда не будет делиться своим стеком с любым другим потоком.
Это не повлияет, пока вы не назовете это на одном объекте.
Ответ 4
Да, но только в двух сценариях:
- если каждый объект, который вы передаете в параметре
o
, неизменный,
- если ваш код гарантирует, что на объект, на который ссылается
o
, работает не более одного потока.
В противном случае - нет, так как внутреннее состояние объекта может быть изменено несколькими потоками одновременно.
Ответ 5
Локальные переменные сохраняются в каждом потоке собственного стека. Это означает, что локальные переменные никогда не разделяются между потоками. Это также означает, что все локальные примитивные переменные являются потокобезопасными.
ИЗМЕНИТЬ
Экземпляр LocalObject в этом примере не возвращается из метода и не передается другим объектам, доступным извне метода sharedMethod()
.
Каждый поток, выполняющий метод sharedMethod()
, будет использовать свой собственный объект o
как параметр.
Таким образом, весь метод sharedMethod()
кажется потокобезопасным.
Единственное исключение, конечно, если один из методов, вызываемых с параметром Object o
as, хранит экземпляр Object o
таким образом, который позволяет получить доступ к нему из других потоков.
Ответ 6
Относитесь к этому пути.
Если ваши потоки не обмениваются общими ресурсами, это может быть проблемой concurrency.
Насколько мы можем судить по предоставленной вами информации, единственное, что можно использовать здесь, - это someObject
. Если он сам потокобезопасен или скопирован для каждого потока, чем ваш код является потокобезопасным вообще, если нет других общих ресурсов.