FULL PRODUCT VERSION :
Both oss:
java version "1.4.2_08"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.4.2_08-b03)
Java HotSpot(TM) Client VM (build 1.4.2_08-b03, mixed mode)
ADDITIONAL OS VERSION INFORMATION :
Linux mole 2.6.11.4-21.9-smp #1 SMP Fri Aug 19 11:58:59 UTC 2005 x86_64 x86_64 x86_64 GNU/Linux
SunOS sol10sqa 5.10 Generic i86pc i386 i86pc
A DESCRIPTION OF THE PROBLEM :
The method random is not thread safe as assured in the API doc.
I have just tested this bug with JDK 1.4.2_10 and discovered that the
bug is also present in the update 10.
In Java 5 the bug doesn't exists anymore.
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
The class attached in the source code section of this bug clarifies this. Two threads are generating random numbers with Math.random(). When proving the set of randoms generated by each thread it occurs that they have occasionally the same number in the set.
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
No output by this class.
ACTUAL -
Double (459.9604747381139) already exists in the set!!!
Double (486.519625428948) already exists in the set!!!
Double (339.88893672717944) already exists in the set!!!
Double (409.237483031485) already exists in the set!!!
Double (693.3775776858432) already exists in the set!!!
Double (490.4033037331255) already exists in the set!!!
Double (129.6123926350977) already exists in the set!!!
Double (161.41201486200575) already exists in the set!!!
Double (268.77128077945014) already exists in the set!!!
Double (311.83956630726016) already exists in the set!!!
Double (301.8506694025317) already exists in the set!!!
Double (182.41583026971554) already exists in the set!!!
Double (463.02838547913615) already exists in the set!!!
[...]
REPRODUCIBILITY :
This bug can be reproduced always.
---------- BEGIN SOURCE ----------
import java.util.HashSet;
import java.util.Set;
/**
* @author Jan Tietjens (jtietjen)
*/
public class MathRandomTest extends Thread {
double [] randomNumbers;
public MathRandomTest(int numberOfRandomNumbers) {
randomNumbers = new double[numberOfRandomNumbers];
}
public void run() {
synchronized(this){
for (int i = 0; i < randomNumbers.length; i++) {
//System.out.println("getName() = " + getName() + " generating RandomNumber");
randomNumbers[i] = (1000 * Math.random());
}
}
}
private double[] getRandomNumbers() {
return randomNumbers;
}
public static void main(String[] args) throws InterruptedException {
while(true){
int numberOfRandomNumbers = 1000;
if (args.length > 0) {
numberOfRandomNumbers = Integer.parseInt(args[0]);
}
MathRandomTest firstMathRandomTest = new MathRandomTest(numberOfRandomNumbers);
firstMathRandomTest.setName("FirstMathRandomTest");
firstMathRandomTest.start();
MathRandomTest secondMathRandomTest = new MathRandomTest(numberOfRandomNumbers);
secondMathRandomTest.setName("SecondMathRandomTest");
secondMathRandomTest.start();
firstMathRandomTest.join();
secondMathRandomTest.join();
Set set= new HashSet();
addResultArrayToSet(firstMathRandomTest, set);
addResultArrayToSet(secondMathRandomTest, set);
}
}
private static void addResultArrayToSet(MathRandomTest firstMathRandomTest, Set set) {
double[] randomNumbers = firstMathRandomTest.getRandomNumbers();
for (int i = 0; i < randomNumbers.length; i++) {
double randomNumber = randomNumbers[i];
Double aDouble = new Double(randomNumber);
if(!set.add(aDouble)){
System.out.println("Double (" + aDouble+ ") already exists in the set!!!");
};
}
}
}
---------- END SOURCE ----------
CUSTOMER SUBMITTED WORKAROUND :
Build a synchronized statement around Math.random().
Both oss:
java version "1.4.2_08"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.4.2_08-b03)
Java HotSpot(TM) Client VM (build 1.4.2_08-b03, mixed mode)
ADDITIONAL OS VERSION INFORMATION :
Linux mole 2.6.11.4-21.9-smp #1 SMP Fri Aug 19 11:58:59 UTC 2005 x86_64 x86_64 x86_64 GNU/Linux
SunOS sol10sqa 5.10 Generic i86pc i386 i86pc
A DESCRIPTION OF THE PROBLEM :
The method random is not thread safe as assured in the API doc.
I have just tested this bug with JDK 1.4.2_10 and discovered that the
bug is also present in the update 10.
In Java 5 the bug doesn't exists anymore.
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
The class attached in the source code section of this bug clarifies this. Two threads are generating random numbers with Math.random(). When proving the set of randoms generated by each thread it occurs that they have occasionally the same number in the set.
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
No output by this class.
ACTUAL -
Double (459.9604747381139) already exists in the set!!!
Double (486.519625428948) already exists in the set!!!
Double (339.88893672717944) already exists in the set!!!
Double (409.237483031485) already exists in the set!!!
Double (693.3775776858432) already exists in the set!!!
Double (490.4033037331255) already exists in the set!!!
Double (129.6123926350977) already exists in the set!!!
Double (161.41201486200575) already exists in the set!!!
Double (268.77128077945014) already exists in the set!!!
Double (311.83956630726016) already exists in the set!!!
Double (301.8506694025317) already exists in the set!!!
Double (182.41583026971554) already exists in the set!!!
Double (463.02838547913615) already exists in the set!!!
[...]
REPRODUCIBILITY :
This bug can be reproduced always.
---------- BEGIN SOURCE ----------
import java.util.HashSet;
import java.util.Set;
/**
* @author Jan Tietjens (jtietjen)
*/
public class MathRandomTest extends Thread {
double [] randomNumbers;
public MathRandomTest(int numberOfRandomNumbers) {
randomNumbers = new double[numberOfRandomNumbers];
}
public void run() {
synchronized(this){
for (int i = 0; i < randomNumbers.length; i++) {
//System.out.println("getName() = " + getName() + " generating RandomNumber");
randomNumbers[i] = (1000 * Math.random());
}
}
}
private double[] getRandomNumbers() {
return randomNumbers;
}
public static void main(String[] args) throws InterruptedException {
while(true){
int numberOfRandomNumbers = 1000;
if (args.length > 0) {
numberOfRandomNumbers = Integer.parseInt(args[0]);
}
MathRandomTest firstMathRandomTest = new MathRandomTest(numberOfRandomNumbers);
firstMathRandomTest.setName("FirstMathRandomTest");
firstMathRandomTest.start();
MathRandomTest secondMathRandomTest = new MathRandomTest(numberOfRandomNumbers);
secondMathRandomTest.setName("SecondMathRandomTest");
secondMathRandomTest.start();
firstMathRandomTest.join();
secondMathRandomTest.join();
Set set= new HashSet();
addResultArrayToSet(firstMathRandomTest, set);
addResultArrayToSet(secondMathRandomTest, set);
}
}
private static void addResultArrayToSet(MathRandomTest firstMathRandomTest, Set set) {
double[] randomNumbers = firstMathRandomTest.getRandomNumbers();
for (int i = 0; i < randomNumbers.length; i++) {
double randomNumber = randomNumbers[i];
Double aDouble = new Double(randomNumber);
if(!set.add(aDouble)){
System.out.println("Double (" + aDouble+ ") already exists in the set!!!");
};
}
}
}
---------- END SOURCE ----------
CUSTOMER SUBMITTED WORKAROUND :
Build a synchronized statement around Math.random().
- relates to
-
JDK-7165808 vm/compiler2/4476333/timeRand.java fails on Solars 10 x86
-
- Closed
-