Подтвердить что ты не робот

Одновременное обращение к Java-методу одноэлементного объекта

У меня вопрос о вызове метода нескольких потоков в Java. Скажем, у нас есть одноэлементный объект, а его класс объявлен следующим образом:

public class SomeClass {
    public void someMethod(SomeValueObject object) {

        if (object.condition1) {
            ...
        }
        if (object.condition2) {
            ...
        }
        if (object.condition3) {
            ...
        }

    }
}

Мне интересно, является ли этот одноэлементный объект одновременно доступным, а его someMethod вызывается с отдельными экземплярами SomeValueObject, есть шанс, что случайный поток изменит ссылку объекта для другого вызова метода потока и беспорядка что? А как насчет полей, созданных внутри области метода? Что я не знаю, существует ли какой-либо отдельный контекст метода для каждого потока, вызывающего метод, или контекст метода одинаковый для всех потоков, вызывающих его? Если это последний случай, мне кажется, мне нужно синхронизированное ключевое слово для обеспечения безопасности потоков или использовать отдельные экземпляры SomeClass для каждого потока (в случае, если мне требуется более быстрое выполнение по оптимизации памяти). Не могли бы вы объяснить мне эту проблему?

P.S. Спасибо за все ваши ответы, ребята!

4b9b3361

Ответ 1

Если все локально, ваш метод является потокобезопасным, как есть. Каждый поток будет иметь свой собственный аргумент объекта в стеке, и они не будут мешать друг другу.

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

Хорошее эмпирическое правило: объект без гражданства является потокобезопасным. Объект с неизменяемым состоянием является потокобезопасным. Объект с изменяемым состоянием не является потокобезопасным, если он не выполняет надлежащую синхронизацию доступа к общему состоянию.

Ответ 2

Нет, потоки не смогут изменять локальные переменные другого потока.

Все переменные, созданные в области метода [локальные переменные] - включая параметры, выделяются в конкретном поточном стеке и, таким образом, не разделяются между двумя потоками.

Однако - все поля классов небезопасны, и если один поток их изменяет - он будет отражен во всех.

Ответ 3

Каждый поток имеет свой собственный стек выполнения. Эта область памяти содержит все локальные переменные и параметры метода. Когда два потока выполняют один и тот же код одновременно, оба используют разные стеки.

Таким образом, невозможно изменить значение параметра метода или локальной переменной другим потоком.

Ответ 4

Что говорили другие. Хотя для nit-pick: в java в стеке выделяются только локальные примитивные переменные и параметры (int, long, boolean и т.д.), Все остальные объекты выделены в куче, и в стек хранятся только ссылки. Но остальные сказали, что каждый вызов метода увидит свою собственную копию локальных переменных.

Обратите внимание, что объекты (в отличие от примитивов), переданные как параметры, не обязательно уникальны для каждого вызова, так как параметры объекта являются просто ссылками. Поэтому, если вы дважды передаете один и тот же объект ввода, то оба будут работать с одним и тем же входом.

Ответ 5

Метод по существу является частью кода. Когда группа потоков вызывает метод, существует отдельная копия метода для каждого стека потоков, поэтому локальные переменные не мешают друг другу.

Если дополнительно, все параметры различны для каждого потока, то есть идеальная изоляция, если только ваш метод не работает с дополнительными совместно используемыми данными внутри своего кода.