[concurrency-interest] _interrupted field visibility bug in OpenJDK 7+

Dr Heinz M. Kabutz heinz at javaspecialists.eu
Wed Nov 7 17:00:06 EST 2012


During a hands-on session today of my new Concurrency Specialist Course, 
one of my students discovered what we think might be an interesting and 
potentially serious bug in the JVM.  It seems that the Server HotSpot in 
OpenJDK 7 may sometimes hoist the value of the _interrupted field.  This 
is interesting, since the value is not stored in Java, but rather in the 
OSThread.hpp file in the jint _interrupted field.  It is also pretty 
serious, because it means we cannot rely on the interrupted status in 
order to shut down threads.  This will affect Future.cancel(), 
ExecutorService.shutdownNow() and a whole bunch of other mechanisms that 
use interruptions to cooperatively cancel tasks.  (Obviously the 
exercise was more involved than the code presented in this email, after 
all the course is aimed at intermediate to advanced Java developers.  So 
please don't expect that this won't happen in your code - I've just 
taken away unnecessary code until we can see the bug without any of the 
paraphernalia that might distract.)

First off, some code that works as expected.  As soon as you interrupt 
the thread, it breaks out of the while() loop and exits:

    public void think() {
        while (true) {
            if (Thread.currentThread().isInterrupted()) break;
        }
        System.out.println("We're done thinking");
    }

However, if you extract the "Thread.currentThread().isInterrupted()" 
into a separate method, then that might be optimized by HotSpot to 
always return false and the code then never ends:

    public void think() {
        while (true) {
            if (checkInterruptedStatus()) break;
        }
        System.out.println("We're done thinking");
    }

    private boolean checkInterruptedStatus() {
        return Thread.currentThread().isInterrupted();
    }

My assumption is that the checkInterruptedStatus() method is 
aggressively optimized and then the actual status is not read again.  
This does not happen with the client hotspot and also not with Java 
1.6.0_37.  It does happen with the 1.8 EA that I've got on my MacBook 
Pro.  The student was using a Windows machine, so this not just a Mac 
problem. 

Here is the complete code:

public class InterruptedVisibilityTest {
    public void think() {
        while (true) {
            if (checkInterruptedStatus()) break;
        }
        System.out.println("We're done thinking");
    }

    private boolean checkInterruptedStatus() {
        return Thread.currentThread().isInterrupted();
    }

    public static void main(String[] args) throws InterruptedException {
        final InterruptedVisibilityTest test =
                new InterruptedVisibilityTest();
        Thread thinkerThread = new Thread("Thinker") {
            public void run() {
                test.think();
            }
        };
        thinkerThread.start();
        Thread.sleep(500);
        thinkerThread.interrupt();
        long timeOfInterruption = System.currentTimeMillis();
        thinkerThread.join(500);
        if (thinkerThread.isAlive()) {
            System.err.println("Thinker did not shut down within 500ms");
            System.err.println("Error in Java Virtual Machine!");
            System.err.println("Interrupted: " + 
thinkerThread.isInterrupted());
            System.err.println();
            System.err.println("(Let's see if the thread ever dies and 
how long it takes)");
            while (thinkerThread.isAlive()) {
                thinkerThread.join(1000);
                if (thinkerThread.isAlive()) {
                    System.err.println("  ... still waiting");
                }
            }
        }
        System.err.println("Finally, the thread has died - that took " +
                (System.currentTimeMillis() - timeOfInterruption) + "ms");
    }
}

As I said, the original code was more involved, but this demonstrates 
the essentials.  I hope some of you might be able to take a look at 
what's going on.

Regards

Heinz
-- 
Dr Heinz M. Kabutz (PhD CompSci)
Author of "The Java(tm) Specialists' Newsletter"
Sun Java Champion
IEEE Certified Software Development Professional
http://www.javaspecialists.eu
Tel: +30 69 75 595 262
Skype: kabutz




More information about the Concurrency-interest mailing list