gpt4 book ai didi

java - 有什么方法可以告诉java线程重新加载缓存吗?

转载 作者:行者123 更新时间:2023-11-30 05:58:05 29 4
gpt4 key购买 nike

学习some answers在这里about volatile 关键字行为 我知道针对 x86 架构的 volatile 读取总是发生在主内存中,这是相当昂贵的。

考虑下一种情况:我有一段代码由 3 个线程执行。类似这样的事情:

class Foo {
private Bar bar;

public Bar read () {
return bar;
}
public void write(Bar bar) {
this.bar = bar;
}
}

而且我还知道,每隔一小段时间(比如说 100 毫秒)就会从 3 个不同的线程进行读取,而写入则每年发生一次。要坚持上下文,请考虑 Bar 不可变 - 这个问题不涵盖与该对象的交互,它只是关于引用本身。

使 bar volatile 将完成它的任务 - 无论哪个线程执行此读取,每次下一次读取都会最终得到正确的数据。但它的成本非常高 - 每次读取都是从主内存中读取。

UPD:所以我的下一个问题是:JVM 上有什么办法可以避免从主内存读取的惩罚吗?也许通过将引用设置为非 volatile 并告诉线程缓存的值可能无效,以便该线程每年仅从主内存读取一次,但不是每 100 毫秒一次?或者至少让它比main ram read便宜。也可以以非阻塞的方式完成吗?也许有一种方法可以使用 happens-before 来处理它?<​​/p>

最佳答案

如果您希望线程正常重用以前的值(即使它已经过时)但偶尔检查更新,只需这样做:

int hits=0;
Bar cache=foo.read(); // Foo.bar is volatile
while(/*...*/) {
if(++hits==100) {
hits=0;
cache=foo.read();
}
cache.doStuff();
}

如果您想打包此逻辑(因为并非所有查找都来自一个函数),请添加一个间接层并为每个线程添加一个 CountFoo ,以便您不共享命中计数器(或支付线程本地存储费用)。

关于java - 有什么方法可以告诉java线程重新加载缓存吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52806397/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com