Безопасность потока для двойной переменной уровня класса - PullRequest
0 голосов
/ 15 апреля 2020

У меня есть двойная переменная уровня класса, и я уже вижу проблему в многопоточной среде. Класс A вызывается несколькими потоками с различным списком. Каков наилучший способ сделать поток var1 безопасным с точки зрения производительности приложения?

class A {

 private double var1= 0.25

 public methodB(List<MyObj> lst){
    for (MyObj obj : lst){
     methodA (obj);
    }
 }

  public void methodA(MyObj obj){
    if(obj.getVal.equals("someString")) {
    var1= 0.15;
    }
  //do something with var1
 } // end of method
} // end of class

Будет ли работать ключевое слово volatile в этом случае?

Ответы [ 2 ]

1 голос
/ 15 апреля 2020

Java предоставляет atomi c пакет , который поддерживает поточно-ориентированное программирование без единой переменной для отдельных переменных. Это особенно полезно, когда вы хотите использовать некоторый примитив в качестве глобальной переменной, но также заботитесь о безопасности потока.

Теперь, эти классы из этого пакета помогут вам, но он не предоставляет прямой AtomicDouble класс, но он говорит вам, как этого добиться, см. Примечание к документации ниже:

Классы Atomi c не являются заменами общего назначения для java .lang.Integer и связанных классов. Они не определяют методы, такие как equals, hashCode и compareTo. (Поскольку ожидается, что переменные atomi c будут мутированными, они не подходят для ключей таблицы ha sh.) Кроме того, классы предоставляются только для тех типов, которые обычно используются в предполагаемых приложениях. Например, нет класса atomi c для представления байта. В тех редких случаях, когда вы хотели бы сделать это, вы можете использовать AtomicInteger для хранения байтовых значений и соответствующего приведения. Вы также можете удерживать плавающие с помощью преобразований Float.floatToRawIntBits (float) и Float.intBitsToFloat (int), а также удваивать с помощью преобразований Double.doubleToRawLongBits (double) и Double.longBitsToDouble (long).



Прочитайте этот ответ .
0 голосов
/ 15 апреля 2020

Создание var1 volatile приведет к загрузке из основной памяти, а не из кэша.

class A {

 private volatile double  var1= 0.25

  public void methodA(){
    if(somethigIsTrue) {
    var1= 0.15;
    }
  //do something with var1
 } // end of method
} //

См. Ответ на этот вопрос относительно проблем с производительностью: Является ли энергозависимым дорогой?

...