FULL PRODUCT VERSION :
On Windows Vista 64-Bit:
java version "1.6.0_10"
Java(TM) SE Runtime Environment (build 1.6.0_10-b33)
Java HotSpot(TM) 64-Bit Server VM (build 11.0-b15, mixed mode)
java version "1.5.0_16"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.5.0_16-b02)
Java HotSpot(TM) 64-Bit Server VM (build 1.5.0_16-b02, mixed mode)
java version "1.7.0-ea"
Java(TM) SE Runtime Environment (build 1.7.0-ea-b39)
Java HotSpot(TM) 64-Bit Server VM (build 14.0-b06, mixed mode)
On Linux Ubuntu 64-Bit:
java version "1.5.0_16"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.5.0_16-b02)
Java HotSpot(TM) Server VM (build 1.5.0_16-b02, mixed mode)
java version "1.5.0_16"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.5.0_16-b02)
Java HotSpot(TM) 64-Bit Server VM (build 1.5.0_16-b02, mixed mode)
java version "1.6.0_10"
Java(TM) SE Runtime Environment (build 1.6.0_10-b33)
Java HotSpot(TM) Server VM (build 11.0-b15, mixed mode)
java version "1.6.0_10"
Java(TM) SE Runtime Environment (build 1.6.0_10-b33)
Java HotSpot(TM) 64-Bit Server VM (build 11.0-b15, mixed mode)
java version "1.7.0-ea"
Java(TM) SE Runtime Environment (build 1.7.0-ea-b39)
Java HotSpot(TM) Server VM (build 14.0-b06, mixed mode)
java version "1.7.0-ea"
Java(TM) SE Runtime Environment (build 1.7.0-ea-b39)
Java HotSpot(TM) 64-Bit Server VM (build 14.0-b06, mixed mode)
ADDITIONAL OS VERSION INFORMATION :
Microsoft Windows [version 6.0.6001] 64-Bit edition
Linux QuadCore 2.6.24-19-generic #1 SMP Wed Aug 20 17:53:40 UTC 2008 x86_64 GNU/Linux
EXTRA RELEVANT SYSTEM CONFIGURATION :
CPU: Q6600
memory: 4Gb
A DESCRIPTION OF THE PROBLEM :
While running two simultaneous threads, the first thread interrupts the second one using Thread.interrupt().
The second thread tests if it has been interrupted calling the Thread.isInterrupted() method which always returns false.
This occurs on a multiprocessor PC running a 64-Bit OS (Vista and Linux).
On Vista 64-Bit, this occurs when using a 64-bit JVM (all versions from 1.5 to 1.7), but does not occur when using a 32-bit JVM.
On Linux 64-bit, this occurs when using a 64-bit JVM (all versions from 1.5 to 1.7) or when using a 32-bit JVM (all versions from 1.5 to 1.7).
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
1. In the following program, the main thread creates a worker thread.
2. The worker thread enters in an infinite loop until it is interrupted. (calling the isInterrupted() method)
3. The main thread waits for the worker thread to die with a timeout of 1 second.
4. The main thread interrupts the worker thread and waits for it to die.
5. The worker thread continuously calls the isInterrupted() method that always return false whereas the thread is interrupted !
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
The Thread.isInterrupted() method should return true and the worker thread should exit.
Here is output of the program executed with a 32-bit JVM on Vista 64-Bit:
Main thread: starts a worker thread...
Main thread: waits at most 1s for the worker thread to die...
Worker thread: running...
Main thread: interrupts the worker thread...
Worker thread: bye
Main thread: worker thread is interrupted
Main thread: waits for the worker thread to die...
Main thread: bye
ACTUAL -
The Thread.isInterrupted() method returns false and the worker thread never exit.
Here is output of the program executed with a 64-bit JVM on Vista 64-Bit:
Main thread: starts a worker thread...
Main thread: waits at most 1s for the worker thread to die...
Worker thread: running...
Main thread: interrupts the worker thread...
Main thread: worker thread is interrupted
Main thread: waits for the worker thread to die...
REPRODUCIBILITY :
This bug can be reproduced always.
---------- BEGIN SOURCE ----------
public class InterruptedTest {
public static void main(String[] args) throws Exception {
Thread workerThread = new Thread("worker") {
public void run() {
System.out.println("Worker thread: running...");
while (!Thread.currentThread().isInterrupted()) {
}
System.out.println("Worker thread: bye");
}
};
System.out.println("Main thread: starts a worker thread...");
workerThread.start();
System.out.println("Main thread: waits at most 1s for the worker thread to die...");
workerThread.join(1000);
if (workerThread.isAlive()) {
System.out.println("Main thread: interrupts the worker thread...");
workerThread.interrupt();
if (workerThread.isInterrupted()) {
System.out.println("Main thread: worker thread is interrupted");
}
System.out.println("Main thread: waits for the worker thread to die...");
workerThread.join();
}
System.out.println("Main thread: bye");
}
}
---------- END SOURCE ----------
CUSTOMER SUBMITTED WORKAROUND :
Calling Thread.yield() before Thread.isInterrupted() bypasses the bug.
Calling Thread.interrupted() instead of Thread.isInterrupted() bypasses the bug.