Сохранить ссылку, а затем назначить новый объект безопасным? - PullRequest
0 голосов
/ 05 апреля 2019

У меня есть статический массив int, который используется несколькими потоками:

static int[] res = new int[10];

В функции я хочу выделить то, что находится в res, и, в основном, сбросить его значения до 0. Является ли следующий поток кода-safe?

final int[] copy = res;
res = new int[10];
// do sth with `copy`

Если нет, то что может быть разумнее, не снижая производительность (кроме использования AtomicInteger или Semaphore).

Ответы [ 2 ]

2 голосов
/ 05 апреля 2019

Это не потокобезопасно. Нет гарантии, когда, если когда-либо, другие потоки увидят изменение статической переменной res.

Вы можете изменить его на:

static volatile int[] res = new int[10];

И тогда другие потоки гарантированно получат его при следующем использовании переменной res.

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

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

Однако, одно предупреждение: другие потоки все еще могут манипулировать значениями в вашей переменной "copy", так как они могли извлечь ссылку и удержать ее.

1 голос
/ 05 апреля 2019

Не безопасно без какой-либо формы синхронизации.

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

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

Вы должны защитить все доступы (от любой поток) до res и к элементам массива с помощью блокировки.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...