Можно ли как-нибудь указать потокам Java перезагрузить кеш? - PullRequest
0 голосов
/ 14 октября 2018

Изучение некоторые ответы здесь о изменчивом поведении ключевых слов Я понял, что нацеливание на энергозависимые чтения архитектуры x86 всегда происходит из основной памяти, котораяЭто довольно дорого.

Рассмотрим следующую ситуацию: у меня есть блок кода, который выполняется, скажем, 3 потока.Примерно так:

class Foo {
  private Bar bar;

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

А также я знаю, что чтение происходит из 3 разных потоков каждый небольшой промежуток времени (скажем, 100 мс), а запись происходит, скажем, раз в год.Чтобы придерживаться контекста, считайте Bar неизменным - этот вопрос не касается взаимодействия с этим объектом, речь идет только о самой ссылке.

Создание bar volatile будет выполнять свою задачу - каждое следующее чтение независимо от того, какой поток выполняет это чтение, закончитсяс правильными данными.Но это обходится очень дорого - каждое чтение будет считываться из основной памяти.

UPD : Поэтому мой вопрос следующий: можно ли на JVM избежать штрафачитать из основной памяти?Может быть, делая ссылку на энергонезависимые и сообщая потокам, что кэшированное значение может быть недопустимым, поэтому эти потоки читают из основной памяти только один раз в год, но не каждые 100 мс?Или, по крайней мере, сделать это дешевле, чем основной баран читать .Это также может быть сделано неблокирующим способом?Может быть, есть способ приблизиться к этому, используя случай-до ?

Ответы [ 2 ]

0 голосов
/ 15 октября 2018

Если вы хотите, чтобы ваши потоки обычно повторно использовали предыдущее значение (даже если оно устарело), ​​но иногда проверяли наличие обновлений, просто сделайте это:

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

Если вы хотите упаковать эту логику (потому чтоне все поиски происходят из одной функции), добавьте слой косвенности и получите CountFoo на поток , чтобы вы не делили счетчики посещений (или не платили за локальное хранилище потока).

0 голосов
/ 14 октября 2018

используйте rw_locks см. http://tutorials.jenkov.com/java-concurrency/read-write-locks.html;это позволяет не иметь блокировки только для чтения и иметь (жесткую) блокировку только при наличии модуля записи

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...