-
Bug
-
Resolution: Fixed
-
P4
-
1.1.6
-
b01
-
generic
-
generic
The Thread.join() contains race condition, it sometimes lost the notification from the thread exit and block forever. The following is the test case which should be reproducable on 1.1.6 win32.
class showbug3 extends Thread
{
// Run the test this long....
// This should be a rather large number to
// be sure to run into the problem (if it is
// still there.)
static final int TEST_LENGTH = 1000000;
// This is the frequency that status output
// happens. On some systems you may wish
// to set this higher or lower.
static final int OUTPUT_EVERY = 1000;
// Our count of thread executions
static int ThreadCount=0;
public void run()
{
// This thread does nothing other than count
// the fact that it ran...
ThreadCount++;
// Running the gc() does not seem to make
// a difference.
// Uncomment the following to run the gc...
//System.gc();
}
static final String status()
{
return ("ThreadCount: "
+ ThreadCount
+ ", Thread.activeCount()="
+ Thread.activeCount()
+ ", mem: "
+ Runtime.getRuntime().freeMemory()
+ " of "
+ Runtime.getRuntime().totalMemory());
}
public static void main(String[] args) throws Throwable
{
// Get our runtime environment.
Runtime runtime=Runtime.getRuntime();
try
{
// Output some initial status...
System.out.println(status());
// Run the test for a long time...
while (ThreadCount < TEST_LENGTH)
{
// Output status every once in a while
for (int i=0;i < OUTPUT_EVERY; i++)
{
// Create a new thread...
Thread work=new showbug3();
// Start it...
work.start();
// Wait for it to finish...
work.join();
}
System.out.println(status());
}
// If we get here, things look good.
System.out.println("Test completed.");
}
catch (Throwable e)
{
// Oops, an exception!!!
System.out.println(status() + " when");
e.printStackTrace(System.out);
}
}
}
class showbug3 extends Thread
{
// Run the test this long....
// This should be a rather large number to
// be sure to run into the problem (if it is
// still there.)
static final int TEST_LENGTH = 1000000;
// This is the frequency that status output
// happens. On some systems you may wish
// to set this higher or lower.
static final int OUTPUT_EVERY = 1000;
// Our count of thread executions
static int ThreadCount=0;
public void run()
{
// This thread does nothing other than count
// the fact that it ran...
ThreadCount++;
// Running the gc() does not seem to make
// a difference.
// Uncomment the following to run the gc...
//System.gc();
}
static final String status()
{
return ("ThreadCount: "
+ ThreadCount
+ ", Thread.activeCount()="
+ Thread.activeCount()
+ ", mem: "
+ Runtime.getRuntime().freeMemory()
+ " of "
+ Runtime.getRuntime().totalMemory());
}
public static void main(String[] args) throws Throwable
{
// Get our runtime environment.
Runtime runtime=Runtime.getRuntime();
try
{
// Output some initial status...
System.out.println(status());
// Run the test for a long time...
while (ThreadCount < TEST_LENGTH)
{
// Output status every once in a while
for (int i=0;i < OUTPUT_EVERY; i++)
{
// Create a new thread...
Thread work=new showbug3();
// Start it...
work.start();
// Wait for it to finish...
work.join();
}
System.out.println(status());
}
// If we get here, things look good.
System.out.println("Test completed.");
}
catch (Throwable e)
{
// Oops, an exception!!!
System.out.println(status() + " when");
e.printStackTrace(System.out);
}
}
}