首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >有没有办法告诉java线程重新加载缓存?

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

Stack Overflow用户
提问于 2018-10-15 03:36:48
回答 2查看 74关注 0票数 1

在研究some answers here about x86关键字行为时,我了解到,以x86架构为目标的易失性读取总是发生在主内存中,这是相当昂贵的。

考虑下一种情况:我有一个由3个线程执行的代码块。大概是这样的:

class Foo {
  private Bar bar;

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

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

让bar变成易失性将完成它的任务--每次下一次读操作,无论哪个线程执行这个读操作,都会得到正确的数据。但它带来了非常高的成本-每次读取都是从主存读取。

UPD:所以我的下一个问题是:在JVM上有什么方法可以避免从主存读取的损失吗?也许通过将引用设为非易失性,并告诉线程缓存值可能无效,所以这个线程一年只从主内存中读取一次,而不是每100ms读取一次?或者至少让它比main ram read便宜。它也可以以非阻塞的方式完成吗?也许有一种方法可以使用发生之前

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2018-10-15 05:25:01

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

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

如果你想打包这个逻辑(因为并不是所有的查找都来自一个函数),添加一个间接层,并且每个线程有一个CountFoo,这样你就不会共享命中计数器(或者为线程本地存储付费)。

票数 1
EN

Stack Overflow用户

发布于 2018-10-15 03:40:33

使用rw_locks查看http://tutorials.jenkov.com/java-concurrency/read-write-locks.html;这允许在只读时没有锁定,只有在有写入器时才有(硬)锁定

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/52806397

复制
相关文章

相似问题

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