Thread.isInterrupted() gibt immer false zurück

Ich bin beim Implementieren von Lasttests über einen sehr fiesen Java-Bug im Multithreadingbereich gestoßen:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
Thread t = new Thread(new Runnable(){

    @Override
    public void run() {
        while(Thread.currentThread().isInterrupted()){
            System.out.println("running into take");
            try {
                System.out.println("received: " + blockingQueue.take());
            } catch (InterruptedException e) {
                System.out.println("caught interrupted exception.");
            }
        }
    }

});

t.start();

blockingQueue.add("foo");

t.interrupt();

Bei diesem Code hätte ich erwartet, dass das t.interrupt() dafür sorgt, dass ein blockendes blockingQueue.take() in den catch-Block springt und danach der Thread terminiert, da Thread.currentThread().isInterrupted() true zurückgibt. Bei mir springt, bei installiertem Java 1.6 32 / 64 Bit, der Thread nach dem catch sofort wieder zurück zu blockingQueue.take() - weil Thread.currentThread.isInterrupted() immer false zurückgibt.

Über Stackoverflow bin ich auf folgenden JVM-Bug gestoßen:

http://bugs.sun.com/view_bug.do?bug_id=6772683

Um einen Thread sicher über ein Thread.interrupt() zu beenden und dabei den Bug zu umgehen verwendet man am besten eine Shutdown-Flag:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
Thread t = new Thread(new Runnable(){

    private boolean shutdown = false;

    @Override
    public void run() {
        while(!shutdown){
            System.out.println("running into take");
            try {
                System.out.println("received: " + blockingQueue.take());
            } catch (InterruptedException e) {
                System.out.println("caught interrupted exception.");
                shutdown = true;
            }
        }
    }

});

t.start();

blockingQueue.add("foo");

t.interrupt();

Damit wird der Thread sauber beendet. Warum der Bug im aktuellen JDK 1.6 immer noch nicht behoben ist, ist mir ein Rätsel. Wie es mit Java 7 / Windows aussieht konnte ich noch nicht testen.

Letzte Aktualisierung: 2012-12-07 07:46:03