Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Multi-thread state visibility in Java: is there a way to turn the JVM into the worst case scenario?

Suppose our code has 2 threads (A and B) have a reference to the same instance of this class somewhere:

public class MyValueHolder {

    private int value = 1;

    // ... getter and setter

}

When Thread A does myValueHolder.setValue(7), there is no guarantee that Thread B will ever read that value: myValueHolder.getValue() could - in theory - keep returning 1 forever.

In practice however, the hardware will clear the second level cache sooner or later, so Thread B will read 7 sooner or later (usually sooner).

Is there any way to make the JVM emulate that worst case scenario for which it keeps returning 1 forever for Thread B? That would be very useful to test our multi-threaded code with our existing tests under those circumstances.

like image 243
Geoffrey De Smet Avatar asked Jul 11 '13 09:07

Geoffrey De Smet


People also ask

How to achieve thread safety in Java?

Using an atomic variable is another way to achieve thread-safety in java. When variables are shared by multiple threads, the atomic variable ensures that threads don’t crash into each other. Final Variables are also thread-safe in java because once assigned some reference of an object It cannot point to reference of another object.

What is the waiting state of a thread in Java?

A thread is in the waiting state due to calling one of the following methods: A thread in the waiting state is waiting for another thread to perform a particular action. Description: Thread state for a waiting thread with a specified waiting time.

What is runnable thread state in Java?

A thread in the runnable state is executing in the Java virtual machine but it may be waiting for other resources from the operating system such as processor. Description: Thread state for a thread blocked waiting for a monitor lock.

How to get the current state of a thread in Java?

In Java, to get the current state of the thread, use Thread.getState() method to get the current state of the thread. Java provides java.lang.Thread.State class that defines the ENUM constants for the state of a thread, as summary of which is given below:


2 Answers

jcstress maintainer here. There are multiple ways to answer that question.

  1. The easiest solution would be wrapping the getter in the loop, and let JIT hoist it. This is allowed for non-volatile field reads, and simulates the visibility failure with compiler optimization.
  2. More sophisticated trick involves getting the debug build of OpenJDK, and using -XX:+StressLCM -XX:+StressGCM, effectively doing the instruction scheduling fuzzing. Chances are the load in question will float somewhere you can detect with the regular tests your product has.
  3. I am not sure if there is practical hardware holding the written value long enough opaque to cache coherency, but it is somewhat easy to build the testcase with jcstress. You have to keep in mind that the optimization in (1) can also happen, so we need to employ a trick to prevent that. I think something like this should work.
like image 61
Aleksey Shipilev Avatar answered Sep 21 '22 06:09

Aleksey Shipilev


It would be great to have a Java compiler that would intentionally perform as many weird (but allowed) transfirmations as possible to be able to break thread unsafe code more easily, like Csmith for C. Unfortunately, such a compiler does not exist (as far as I know).

In the meantime, you can try the jcstress library* and exercise your code on several architectures, if possible with weaker memory models (i.e. not x86) to try and break your code:

The Java Concurrency Stress tests (jcstress) is an experimental harness and a suite of tests aid research in the correctness of concurrency support in the JVM, class libraries, and hardware.

But in the end, unfortunately, the only way to prove that a piece of code is 100% correct is code inspection (and I don't know of a static code analysis tool able to detect all race conditions).

*I have not used it and I am unclear which of jcstress and the java-concurrency-torture library is more up to date (I would suspect jcstress).

like image 42
assylias Avatar answered Sep 19 '22 06:09

assylias