有没有办法告诉java线程重新加载缓存?

在这里研究了一些 关于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 immutable - 这个问题不包括与这个对象的交互,它只是关于引用本身。


使 bar 可变将完成它的任务 - 无论哪个线程执行此读取,每次下一次读取都会以正确的数据结束。但它带来了非常高的成本——每次读取都是从主内存读取。


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


繁星淼淼
浏览 237回答 2
2回答

桃花长相依

如果您希望您的线程通常重用以前的值(即使它已经过时)但偶尔检查更新,只需这样做:int hits=0;Bar cache=foo.read();  // Foo.bar is volatilewhile(/*...*/) {  if(++hits==100) {    hits=0;    cache=foo.read();  }  cache.doStuff();}如果您想打包此逻辑(因为并非所有查找都来自一个函数),请添加一个间接层并为CountFoo 每个线程设置一个,这样您就不会共享命中计数器(或为线程本地存储付费)。

侃侃无极

使用 rw_locks 见http://tutorials.jenkov.com/java-concurrency/read-write-locks.html ;这允许在只读时没有锁定,并且只有在有写入者时才具有(硬)锁定
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Java