2

As per the book “Java concurrency in practice”, the below code might execute forever or value of number may still be 0 when ready is true and the recommendation was to define the variables as volatile. However the below listed program always seems to return the correct value (42) instead of stale value even after I tried this multiple times. Is this a phenomenon that occurs very rarely?

public class NoVisibility {
    private static boolean ready;
    private static int number;

    private static class ReaderThread extends Thread{
        public void run(){
            System.out.println("Thread started =" + ready + " " + number);
            while(!ready){
                Thread.yield();
            }
            System.out.println("value is" + number);
        }
    }

    public static void main(String[] args) throws InterruptedException {
        new ReaderThread().start();
        Thread.sleep(10000);
        number = 42;
        ready = true;
    }
}
6
  • Whats the output you are getting and what are you expecting to be the output exactly? Commented Nov 16, 2020 at 0:51
  • I’m expecting to loop to not end or display 0. But I’m getting 42 as output. Commented Nov 16, 2020 at 0:53
  • Well, when you call Thread.yield() inside the ReaderThread it allows the main thread to run first. The main thread waits 10000 milis and then changes those two variables.And also terminates the child thread. I don't see whats unexpected here Commented Nov 16, 2020 at 1:04
  • I tried using loops and multiple threads, also couldn't get it to mess up. I guess this needs to be interpreted as "don't use class fields for inter-process communication", with an example of what sort of thing to avoid, even if in this simple case and with more recent JVMs the provided code works fine. Commented Nov 16, 2020 at 1:20
  • 1
    @Dennishofken As per the book, you cannot be certain that ReaderThread will “see” the updated value for the instance variables thereby causing an infinite loop. Even if it sees the updated value, there could be occasions where ready is set to true before number is set to 42. Hence this could result in value being printed as 0. The safe way to do it by either synchronization or by setting the instance fields to volatile in this specific example. Commented Nov 16, 2020 at 1:29

2 Answers 2

4

Is this a phenomenon that occurs very rarely

Yes, rare. However, given computers that do things billions of times per second, rare is quite common.

Whenever accessing resources across threads, you must address thread-safety. Otherwise, your app in deployment will suffer sporadic bugs that are terribly difficult if not impossible to solve.

By this same logic, testing for concurrency bugs is notoriously difficult, as you have seen in your Question.

Always look to avoid threaded code where possible. For example, utilize immutable objects or defensive copies.

Required reading: Java Concurrency in Practice by Brian Goetz, et al.

Sign up to request clarification or add additional context in comments.

2 Comments

Re: "Required reading: Java Concurrency in Practice by Brian Goetz, et al.": Since the first six words of the question are "As per Java concurrency in practice", I think it's fair to say that that comment is not needed.
@ruakh That first sentence is not at all clear about being a reference to a book. And Stack Overflow is not email — I write Answers for the thousands of other readers, not for the person asking the Question.
1

Author says server JVM performs more optimisation then the client JVM. a paragraph fromt he book

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.