-1

I have a class level double variable and I already see a problem in multi- threading environment. Class A is called by multiple threads with different list. What is the best way to make var1 thread safe considering it s performance critical application?

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

Will volatile keyword work in this case?

heart_coder
  • 189
  • 13
  • 2
    I depends on the actual usecase. Like what operations do you want to be atomic and what don't have to be. The simplest option would be to make `methodA` synchronized. – Amongalen Apr 15 '20 at 14:09
  • We need a lot more detail. What kind of application? Why is it multi-threaded? What is the nature of class A? Is it a data class? A data repository? – VGR Apr 15 '20 at 14:13
  • I need a separate copy of var1 for each thread. If a thread changes the value of var1, it should not be reflected in thread2. @Amongalen. – heart_coder Apr 15 '20 at 15:22
  • 1
    Separate copy within a *single instance* of `A`? That sounds like a job for [ThreadLocal](https://docs.oracle.com/en/java/javase/14/docs/api/java.base/java/lang/ThreadLocal.html). Or, just have each thread make its own instance of `A`. – VGR Apr 15 '20 at 15:26

2 Answers2

1

Java provides atomic package that support lock-free thread-safe programming on single variables. This is especially useful when you want to use some primitive as global variable but also care about thread-safety.

Now, this classes from this package will help you but it doesn't provide a direct AtomicDouble class, but it tells you how to achieve that, see below note from the documentation:

Atomic classes are not general purpose replacements for java.lang.Integer and related classes. They do not define methods such as equals, hashCode and compareTo. (Because atomic variables are expected to be mutated, they are poor choices for hash table keys.) Additionally, classes are provided only for those types that are commonly useful in intended applications. For example, there is no atomic class for representing byte. In those infrequent cases where you would like to do so, you can use an AtomicInteger to hold byte values, and cast appropriately. You can also hold floats using Float.floatToRawIntBits(float) and Float.intBitsToFloat(int) conversions, and doubles using Double.doubleToRawLongBits(double) and Double.longBitsToDouble(long) conversions.



Do read this answer as well.
hagrawal7777
  • 14,103
  • 5
  • 40
  • 70
0

Making var1 volatile will force a load from main memory and not from cache.

class A {

 private volatile double  var1= 0.25

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

Refer to the answer to this question regarding performance concerns: Is volatile expensive?

John
  • 1
  • 1