Java Solaris Communities Sun Store Join SDN My Profile Why Join?
 
Bug Database
Bug Detail
Quick Lists
Top 25 Bugs
Top 25 RFE's
Recently Closed Bugs
Printable Page Printable Page


Bug Database
Bug ID: 6633113
Votes 0
Synopsis test/java/util/concurrent/SynchronousQueue/Fairness.java fails intermittently
Category java:classes_util_concurrent
Reported Against
Release Fixed 7(b25)
State 10-Fix Delivered, bug
Priority: 3-Medium
Related Bugs
Submit Date 22-NOV-2007
Description
Regression test
test/java/util/concurrent/SynchronousQueue/Fairness.java 
fails intermittently with output like

1
Exception in thread "main" java.lang.Exception: No fair!
	at Fairness.testFairness(Fairness.java:51)
	at Fairness.main(Fairness.java:56)

Seems most easy to reproduce on linux-i586
Posted Date : 2007-11-22 00:13:42.0
Work Around
N/A
Evaluation
The System.sleep(100) is un unreliable way to serialize thread execution.
Some other j.u.c. mechanisms need to be used to guarantee serial execution.
Consider using an array of ReentrantLocks or CountdownLatches
Posted Date : 2007-11-22 00:13:42.0

Here's the proposed patch:

diff --git a/test/java/util/concurrent/SynchronousQueue/Fairness.java b/test/java/util/concurrent/SynchronousQueue/Fairness.java
--- a/test/java/util/concurrent/SynchronousQueue/Fairness.java
+++ b/test/java/util/concurrent/SynchronousQueue/Fairness.java
@@ -23,36 +23,49 @@
 
 /*
  * @test
- * @bug 4992438
- * @compile -source 1.5 Fairness.java
- * @run main Fairness
+ * @bug 4992438 6633113
  * @summary Checks that fairness setting is respected.
  */
 
 import java.util.concurrent.*;
+import java.util.concurrent.locks.*;
 
 public class Fairness {
     private static void testFairness(boolean fair,
                                      final BlockingQueue<Integer> q)
-        throws Exception
+        throws Throwable
     {
-        for (int i = 0; i < 3; i++) {
-            final Integer I = new Integer(i);
-            new Thread() { public void run() {
-                try { q.put(I); } catch (Exception e) {}
-            }}.start();
-            Thread.currentThread().sleep(100);
+        final ReentrantLock lock = new ReentrantLock();
+        final Condition ready = lock.newCondition();
+        final int threadCount = 10;
+        final Throwable[] badness = new Throwable[1];
+        lock.lock();
+        for (int i = 0; i < threadCount; i++) {
+            final Integer I = i;
+            Thread t = new Thread() { public void run() {
+                try {
+                    lock.lock();
+                    ready.signal();
+                    lock.unlock();
+                    q.put(I);
+                } catch (Throwable t) { badness[0] = t; }}};
+            t.start();
+            ready.await();
+            // Probably unnecessary, but should be bullet-proof
+            while (t.getState() == Thread.State.RUNNABLE)
+                Thread.yield();
         }
-        for (int i = 0; i < 3; i++) {
-            int j = q.take().intValue();
-            System.err.printf("%d%n",j);
+        for (int i = 0; i < threadCount; i++) {
+            int j = q.take();
             // Non-fair queues are lifo in our implementation
-            if (fair ? j != i : j != 2-i)
-                throw new Exception("No fair!");
+            if (fair ? j != i : j != threadCount - 1 - i)
+                throw new Error(String.format("fair=%b i=%d j=%d%n",
+                                              fair, i, j));
         }
+        if (badness[0] != null) throw new Error(badness[0]);
     }
 
-    public static void main(String[] args) throws Exception {
+    public static void main(String[] args) throws Throwable {
         testFairness(false, new SynchronousQueue<Integer>());
         testFairness(false, new SynchronousQueue<Integer>(false));
         testFairness(true,  new SynchronousQueue<Integer>(true));
Posted Date : 2008-03-06 23:57:51.0
Comments
  
  Include a link with my name & email   


PLEASE NOTE: JDK6 is formerly known as Project Mustang