3

Reading a book, and this code comes up:

public class Test {

    private static boolean ready = false;
    private static int number = 0;

    public static class ListenerThread extends Thread {

        public void run() {

            while(!ready) {
                Thread.yield();
            }
            System.out.println(number);

        }

    }

    public static void main (String[] args) {

        new ListenerThread().start();
        number = 10;
        ready = true;

    }

}

The main points I was surprised about were mentioned by the author relatively quickly.

  1. They said ListenerThread might never terminate. I thought about this for a few days (in the back of my head), and my only conclusion is that it might be cached by that ListenerThread. Is that true? Would making ready volatile solve the problem (since it shouldn't cache it anymore)?

  2. They also said the program might print 0. I understand now that Java might reorder the instructions, so ready becomes true to another thread before number is changed. Is there any method (technique), besides putting those instructions in a synchronized blocks solve the problem (on a central lock value)? I was thinking maybe implement notify()/wait(), but I feel it would suffer the same consequences. What is the best way to avoid the problem?

Thank you!

EDIT:

I just feel that I've read through a lot of code, and few bothered to protect against reordering in multiple threads. How common is this?

2 Answers 2

8

my only conclusion is that it might be cached by that ListenerThread. Is that true? Would making ready volatile solve the problem (since it shouldn't cache it anymore)?

Not only cached, but the JIT can inline the value on the basis that the thread never changes it. i.e. it becomes hard coded.

Using volatile prevent such assumptions being made. It will force it to read a cache consistent copy each time.

I understand now that Java might reorder the instructions,

Not only Java, but the CPU can re-order instructions. The JIT is aware that the CPU can do this re-ordering and AFAIK it rarely needs to as it assumes the CPU will do a good job.

BTW Accessing a volatile variable also prevent instruction re-ordering so making ready volatile solves both problems.

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

Comments

3

They said ListenerThread might never terminate. I thought about this for a few days, and my only conclusion is that it might be cached by that ListenerThread. Is that true? Would making ready volatile solve the problem (since it shouldn't cache it anymore)?

That is true, yes. And yes, declaring the variable volatile changes the memory access semantics of the variable, and forces a reread each time the variable is accessed.

They also said the program might print 0. I understand now that Java might reorder the instructions, so ready becomes true to another thread before number is changed. Is there any method, besides putting those two instructions in a synchronized blocks solve the problem? I was thinking maybe implement notify()/wait(), but I feel it would suffer the same consequences.

This is because there is no guarantee of ordering, so the JVM is free to reorder variable assignments. If you want to make number equally visible to both parties, you have to prevent this reordering, and as @PeterLawrey says, making ready volatile is enough for this.

4 Comments

The OP didn't mention synchronizing on Test, rather using synchronized blocks (possibly on some mutual lock which would work).
@yair, yes, I thought of putting the ready check & print, and variable assignments in synchronized blocks on a random lock variable, but that would seem prohibitively slow.
Yes, it was just unclear what the OP meant by "synchronized block". Editing.
@jsn it is probably way faster than an eyeblink ;)

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.