首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Java中的线程可以缓存最后一个字段吗?

Java中的线程可以缓存最后一个字段吗?
EN

Stack Overflow用户
提问于 2018-11-27 11:03:53
回答 3查看 191关注 0票数 1

假设我声明了以下数组:

代码语言:javascript
复制
private final int[] array = new int[10];

现在,如果我启动10个线程,每个线程都将一个值写入自己的键(线程1写到array[0],线程2写到array[1],等等),会不会有线程尝试缓存数组,或者所有更改都将在主内存中进行?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2018-11-27 12:21:05

线程可以缓存任何非易失性值.

特别是,线程的代码可以将线程不改变的boolean值内联到代码中。在重新编译更改之前,线程可能不会检测到更改。

在这种情况下,数组引用和数组中的值都将被缓存,但很可能会在一段时间后看到新值。

final的使用并没有真正的区别。原因之一是反射允许您更改final字段。

有这样一个线程安全数组的一个更干净的方法是使用Java5.0中添加的AtomicIntegerArray

代码语言:javascript
复制
final AtomicIntegerArray array = new AtomicIntegerArray(10);

public void increment(int n) {
    array.incrementAndGet(n);
}
票数 2
EN

Stack Overflow用户

发布于 2018-11-27 11:21:09

不,final没有单个数组元素的可见性语义,即使是易失性也只能保证引用突变本身上的在订货前发生,而不是元素。为此,您需要同步或使用CopyOnWriteArrayList

票数 1
EN

Stack Overflow用户

发布于 2018-11-27 11:28:41

更新

final修饰符确保所有Thread-s都能看到该引用的初始化值。这一点很重要:final关键字只引用数组,而不引用存储在该数组中的值。

原始答案

我们不知道会发生什么。JVM可能缓存值,也可能不缓存值。我建议不要对此产生任何依赖。

我想你会想要一些能见度。通常,您可以使用volatile关键字或使用synchronization强制可见性。在这种情况下,您有一个数组if整数。

AtomicInteger-s数组

您可以用AtomicInteger -s数组替换它:

代码语言:javascript
复制
private final AtomicInteger[] array = new AtomicInteger[10];

但在这种情况下,您必须以不同的方式操作这些值:

代码语言:javascript
复制
array[0] = new AtomicInteger(0);
array[0].incrementAndGet();

并发列表

另一种方法是使用并发列表,如CopyOnWriteArrayList或使用Collections.synchronizedList()包装方法:

代码语言:javascript
复制
// option 1
private final List<Integer> list = Collections.synchronizedList(new ArrayList<>());

// option 2
private final List<Integer> list = new CopyOnWriteArrayList<>();

无论哪种方式,您的访问器都将与array的访问器有所不同。列表初始化是最棘手的部分:

代码语言:javascript
复制
// this prevents all kinf of OutOfBoundsException-s
for (int i = 0; i < 10; i++) {
    list.add(0);
}
// and now you can use it
list.set(0, list.get(0) + 1);

并发映射

您还可以使用map,因此可以跳过有问题的初始化:

代码语言:javascript
复制
private final ConcurrentMap<Integer, Integer> map = new ConcurrentHashMap<>();
// ...
map.putIfAbsent(0, 0);
map.put(0, map.get(0) + 1);
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/53498255

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档