Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Does increment operators e.g count++; stores volatile data thread-locally?

Tags:

java

My goal is to understand how the volatile keyword works.

My expected result: The assertEquals did not fail.

My actual result: The assertEquals fail. (sometimes the actual count value are between 9991 to 9999).

I am assuming this happens because of the increment operators / count++ equals to

public void increment() {
  int temp = count;
  count = temp + 1;
}

and considering that, the temp attribute is stored thread-locally. Am I true?

Counter.java

public class Counter implements Runnable {
  private volatile int count = 0;
  public int getCount() { return count; }
  public void increment() { count++; }
  @Override
  public void run() { increment(); }
}

CounterTest.java

public class CounterTest {
  @Test
  void increment() {
    ExecutorService service = Executors.newFixedThreadPool(10);
    Counter counter = new Counter();
    for (int i = 0; i < 10000; i++) {
      service.execute(counter);
    }
    service.shutdown();
    service.awaitTermination(1, TimeUnit.SECONDS);
    assertEquals(10000, counter.getCount());
  }
}
like image 838
kidfrom Avatar asked May 19 '21 14:05

kidfrom


People also ask

Can local variables be volatile?

Operations you perform locally will not have visibility or interference issues by other threads so it does not make sense to declare local variable volatile.

What is volatile variable in multithreading?

Volatile keyword is used to modify the value of a variable by different threads. It is also used to make classes thread safe. It means that multiple threads can use a method and instance of the classes at the same time without any problem. The volatile keyword can be used either with primitive type or objects.

Is volatile useful for threads?

volatile is unnecessary and useless for synchronization between threads. Threading libraries can't be implemented in terms of volatile ; it has to rely on platform-specific details anyway, and when you rely on those, you no longer need volatile .

Are volatile variables thread safe?

Therefore, the volatile keyword does not provide thread safety when non-atomic operations or composite operations are performed on shared variables. Operations like increment and decrement are composite operations.


1 Answers

My goal is to understand how the volatile keyword works

If that is your goal, then start looking at the JLS and the guarantees that volatile offers. volatile is not about atomic operations, i.e.: count++; is not atomic. As such, this :

assertEquals(10000, counter.getCount());

can fail, at any point in time.

volatile is about what some thread is supposed to "observe" when it has observed a written value to that variable, by another thread. There are many, literally many examples of what this means, probably the most famous one is this. Start there and build your knowledge up to the JLS.

like image 198
Eugene Avatar answered Oct 18 '22 03:10

Eugene