-
Bug
-
Resolution: Fixed
-
P4
-
1.2.0
-
beta
-
generic
-
generic
Name: krT82822 Date: 05/10/99
/*
* POET SDK Java Edition
* Copyright (c) POET Software 1999
*
* Test module
* kwz 10. May 1999, created
*/
//// //// //// //// //// //// //// //// //// //// //// //// //// //// //// ////
import java.text.*;
import java.util.*;
/**
* The Collators of old JDK versions are thread safe.
* JDK 1.2's Collator is not thread-safe.
* Question to SUN: Is that the intended behavior or a bug?
*
* The test below compares a string to itself and
* prints a line when the test result is != 0, which
* should never happen. Each thread has its own String,
* but shares the same Collator with other threads. Just call
*
* java CollatorTest
*
* With Java 1.2 I get lots of lines like
* ConcurrentTestObject-4 == ConcurrentTestObject-4 but compare returns 1
* ConcurrentTestObject-5 == ConcurrentTestObject-5 but compare returns 1
* ConcurrentTestObject-6 == ConcurrentTestObject-6 but compare returns 1
* ConcurrentTestObject-8 == ConcurrentTestObject-8 but compare returns 1
* ConcurrentTestObject-9 == ConcurrentTestObject-9 but compare returns -1
* ConcurrentTestObject-0 == ConcurrentTestObject-0 but compare returns -1
* ConcurrentTestObject-1 == ConcurrentTestObject-1 but compare returns -1
* ConcurrentTestObject-7 == ConcurrentTestObject-7 but compare returns 1
*
* java -version
* java version "1.2"
* Classic VM (build JDK-1.2-V, native threads)
*
* This happens in calls to RuleBasedCollator after version 1.23 98/05/20
* Prior versions seem to work, I looked into the sources of 1.22 98/04/22
* they do not contain this bug.
*
* From analyzing the sources it can be said that the later version of
* RuleBasedCollator caches CollationElementIterator objects between the
* calls to compare(). Unfortunately, it doesn't synchronize on them.
* Thus, if two threads call compare() concurrently the state of the
* iterators is undefined, resulting in undefined comparisons.
*
* The question is: is this intended behavior? Or did the programmer
* just forget to synchronize?
*
* Problem: Old code, i.e., code only tested against the library of JDK1.1.6,
* may be unaware of this problem and breaks with strange errors when used
* with newer libraries.
*
* Since the documentation nowhere explicitely states that Collator.compare()
* is no longer thread-safe, I would consider this a bug.
*
* A simple fix would be to place a synchronize( this )
* around the bodies of all public methods that change the
* internal state of RuleBasedCollator.
*
* A workaround is to synchronize externally or create a new Collator for
* each Thread. But this means that old code would have to be changed.
*
*
* @author Kai W. Zimmermann
*/
public class CollatorTest
{
static Collator coll;
private static class CollatorThread extends Thread {
String myPrefix;
int myNumber;
public String string1;
boolean doTestMany;
public CollatorThread ( String prefix, int number, boolean doTestMany ) {
myPrefix = prefix;
myNumber = number;
string1 = prefix + (number%10);
this.doTestMany = doTestMany;
}
public void run () {
if( doTestMany )
testMany();
else
testOne();
}
public void testOne () {
for( int i = 0; i<1000; ++i) {
int result;
result = coll.compare(string1,string1);
if( result != 0 ) {
// Oops, how comes?
System.out.println( string1+" == "+string1+" but compare returns "+ result );
}
}
}
public void testMany () {
for( int i = 0; i<1000; ++i) {
int result;
// result = coll.getCollationKey(string1).compareTo(coll.getCollationKey(myPrefix+(i%10)));
result = coll.compare(string1,myPrefix+(i%10));
if( (myNumber%10)<(i%10) ) {
if( result != -1 ) {
System.out.println( string1+" < "+(myPrefix+(i%10))+" but compare returns "+ result );
}
}
else if( (myNumber%10)>(i%10) ) {
if( result != +1 ) {
System.out.println( string1+" > "+(myPrefix+(i%10))+" but compare returns "+ result );
}
}
else {
if( result != 0 ) {
System.out.println( string1+" == "+(myPrefix+(i%10))+" but compare returns "+ result );
}
}
}
}
}
public static void main(String[] args)
{
coll = Collator.getInstance();
coll.setStrength(Collator.TERTIARY);
for( int j = 0; j<20; ++j ) {
new CollatorThread("ConcurrentTestObject-",j,false).start();
}
}
}
(Review ID: 58024)
======================================================================