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: 6374942
Votes 0
Synopsis Improve thread safety of collection .equals() methods
Category java:classes_util_concurrent
Reported Against
Release Fixed
State 6-Fix Understood, bug
Priority: 3-Medium
Related Bugs
Submit Date 20-JAN-2006
Description
Collections.newSetFromMap().equals is failing with ConcurrentSkipListMap.

The following testcase will fail on the average of 13 times out of 100.
<testcase>
import java.util.Set;
import static java.util.Collections.*;
import java.util.concurrent.ConcurrentSkipListMap;
import java.util.concurrent.ConcurrentSkipListSet;

public class Test1 {
    private static void testSet(final Set<Integer> s1,
				final Set<Integer> s2,
				final boolean checkToString) {
        final int iterations = 100000;
        final Integer two = Integer.valueOf(2);
        final Thread t1 = new CheckedThread() { public void realRun() {
            for (int i = 0; i < iterations; i++) {
                s2.add(two);
                s2.remove(two);
            }}};
        t1.start();
        for (int i = 0; i < iterations; i++) {
                check(s1.equals(s1));
                check(s2.equals(s2));
                check(! s1.equals(s2));
                check(! s2.equals(s1));
                equal(s1.toString(),s1.toString());
                notEqual(s1.toString(),s2.toString());
                notEqual(s2.toString(),s1.toString());
        }
        try { t1.join(); } catch (Throwable t) { unexpected(t); }
    }
    public static void realMain(String... arg) throws Throwable{
        System.out.println("SetFromMap");
        Set<Integer>  s1 = newSetFromMap(new ConcurrentSkipListMap<Integer,Boolean>());
        Set<Integer>  s2 = newSetFromMap(new ConcurrentSkipListMap<Integer,Boolean>());
        s1.add(1);
        testSet(s1,s2,true);
        System.out.println("Direct");
        Set<Integer>   customer  = new ConcurrentSkipListSet<Integer>();
        Set<Integer>  s4 = new ConcurrentSkipListSet<Integer>();
         customer .add(1);
        testSet( customer ,s4,true);
    }
     static volatile int passed = 0, failed = 0;
    static void pass() {passed++;}
    static void fail() {failed++; Thread.dumpStack();}
    static void fail(String msg) {System.out.println(msg); fail();}
    static void unexpected(Throwable t) {failed++; t.printStackTrace();}
    static void check(boolean cond) {if (cond) pass(); else fail();}
    static void equal(Object x, Object y) {
	if (x == null ? y == null : x.equals(y)) pass();
	else fail(x + " not equal to " + y);}
    static void notEqual(Object x, Object y) {
	if (x == null ? y == null : x.equals(y)) fail(x + " equal to " + y);
	else pass();}
    public static void main(String[] args) throws Throwable {
	try {realMain(args);} catch (Throwable t) {unexpected(t);}
	System.out.printf("%nPassed = %d, failed = %d%n%n", passed, failed);
	if (failed > 0) throw new AssertionError("Some tests failed");}
    private static abstract class CheckedThread extends Thread {
    public abstract void realRun() throws Throwable;
    public void run() {
        try { realRun(); } catch (Throwable t) { unexpected(t); }}}
}
</testcase>

newSetFromMap spec says:
"Returns a set backed by the specified map. The resulting set displays the same ordering, *concurrency*, and performance characteristics as the backing map."

In the above testcase, when  ConcurrentSkipListSet is directly used testcase will pass always but when set is constructed from newSetFromMap(ConcurrentSkipListMap). The testcase will fail.

Tested on :
<java-version>
java version "1.6.0-rc"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.6.0-rc-b66)
Java HotSpot(TM) Client VM (build 1.6.0-rc-b66, mixed mode)
</java-version>
Posted Date : 2006-01-20 10:36:45.0

testbase: /net/sqindia.india/export/disk03/coresqe/j2se_sqe_libs_ws/mustang_libs_ws
failing testcase: java_util/Collections/SetFromMap/ConcurrentSkipList/ConcurrentSkipListTest02
Posted Date : 2006-03-16 17:45:13.0
Work Around
N/A
Evaluation
Various .equals() methods implicitly assume that "this" or the
argument collection is not being concurrently mutated during
method execution.  It would be good to improve this, 
especially for the .equals() methods of concurrent collections.
Posted Date : 2006-01-20 22:57:25.0

One can argue that the semantics of equals() when comparing mutating collections
is unclear, and that mutable set equality should be identity comparison,
while immutable set equality should be content comparison.
But Java is not ML.
Posted Date : 2006-02-04 19:11:52.0
Comments
  
  Include a link with my name & email   


PLEASE NOTE: JDK6 is formerly known as Project Mustang