维护参考,然后分配新的对象线程安全吗?

时间:2019-04-05 00:53:27

标签: java multithreading concurrency

我有一个在线程之间共享的静态int数组:

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

在一个函数中,我想隔离res中的内容,并且基本上将其值重置为0。以下代码是线程安全的吗?

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

如果没有,那么不破坏性能(而不是使用AtomicInteger或Semaphore)是一种更聪明的方法。

2 个答案:

答案 0 :(得分:2)

这不是线程安全的。无法保证其他线程何时会看到对静态变量res的更改。

您可以将其更改为:

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

然后将保证其他线程下次使用res变量来提取它。

在这种特殊情况下,您仅重置为零,并且不依赖于先前的res值,这可能就足够了。

如果您确实依赖先前的值(或其他共享变量),则需要在线程之间实现进一步的同步。

但是,一个警告:其他线程可能仍在操纵“ copy”变量中的值,因为它们可能已经检索了引用并保留了该引用。

答案 1 :(得分:1)

没有某种形式的同步是不安全的。

一个线程是否可以执行示例中所示的引用交换,而另一个线程正在更新数组?如果是这样,那么该代码非常是不安全的,因为不同的线程可能在res所引用的数组上存在分歧,因此更新可能会丢失。

即使唯一更新数组的线程与进行交换的线程相同,代码 still 也不安全,因为其他线程可能会看到对数组成员的更新乱序彼此之间,并且对于res的重新分配而言,是混乱的。

您应该保护对锁res所有访问(来自 any 线程)和带锁的数组成员。