This commit is contained in:
Lana Steuck 2011-02-09 10:28:20 -08:00
commit 6641ee235d
4 changed files with 177 additions and 142 deletions

View File

@ -690,7 +690,7 @@ class Thread implements Runnable {
/* Notify the group that this thread is about to be started /* Notify the group that this thread is about to be started
* so that it can be added to the group's list of threads * so that it can be added to the group's list of threads
* and the group's unstarted count can be decremented. */ * and the group's unstarted count can be decremented. */
group.threadStarting(this); group.add(this);
boolean started = false; boolean started = false;
try { try {

View File

@ -867,21 +867,6 @@ class ThreadGroup implements Thread.UncaughtExceptionHandler {
} }
} }
/**
* Notifies the group that the thread {@code t} is about to be
* started and adds the thread to this thread group.
*
* The thread is now a fully fledged member of the group, even though
* it hasn't been started yet. It will prevent the group from being
* destroyed so the unstarted Threads count is decremented.
*/
void threadStarting(Thread t) {
synchronized (this) {
add(t);
nUnstartedThreads--;
}
}
/** /**
* Adds the specified thread to this thread group. * Adds the specified thread to this thread group.
* *
@ -910,6 +895,12 @@ class ThreadGroup implements Thread.UncaughtExceptionHandler {
// This is done last so it doesn't matter in case the // This is done last so it doesn't matter in case the
// thread is killed // thread is killed
nthreads++; nthreads++;
// The thread is now a fully fledged member of the group, even
// though it may, or may not, have been started yet. It will prevent
// the group from being destroyed so the unstarted Threads count is
// decremented.
nUnstartedThreads--;
} }
} }

View File

@ -36,7 +36,7 @@ package java.util;
* @author Jon Bentley * @author Jon Bentley
* @author Josh Bloch * @author Josh Bloch
* *
* @version 2011.01.21 m765.827.12i:5\7pm * @version 2011.02.11 m765.827.12i:5\7pm
* @since 1.7 * @since 1.7
*/ */
final class DualPivotQuicksort { final class DualPivotQuicksort {
@ -115,7 +115,7 @@ final class DualPivotQuicksort {
* Index run[i] is the start of i-th run * Index run[i] is the start of i-th run
* (ascending or descending sequence). * (ascending or descending sequence).
*/ */
int[] run = new int[MAX_RUN_COUNT]; int[] run = new int[MAX_RUN_COUNT + 1];
int count = 0; run[0] = left; int count = 0; run[0] = left;
// Check if the array is nearly sorted // Check if the array is nearly sorted
@ -555,7 +555,7 @@ final class DualPivotQuicksort {
* Index run[i] is the start of i-th run * Index run[i] is the start of i-th run
* (ascending or descending sequence). * (ascending or descending sequence).
*/ */
int[] run = new int[MAX_RUN_COUNT]; int[] run = new int[MAX_RUN_COUNT + 1];
int count = 0; run[0] = left; int count = 0; run[0] = left;
// Check if the array is nearly sorted // Check if the array is nearly sorted
@ -1027,7 +1027,7 @@ final class DualPivotQuicksort {
* Index run[i] is the start of i-th run * Index run[i] is the start of i-th run
* (ascending or descending sequence). * (ascending or descending sequence).
*/ */
int[] run = new int[MAX_RUN_COUNT]; int[] run = new int[MAX_RUN_COUNT + 1];
int count = 0; run[0] = left; int count = 0; run[0] = left;
// Check if the array is nearly sorted // Check if the array is nearly sorted
@ -1499,7 +1499,7 @@ final class DualPivotQuicksort {
* Index run[i] is the start of i-th run * Index run[i] is the start of i-th run
* (ascending or descending sequence). * (ascending or descending sequence).
*/ */
int[] run = new int[MAX_RUN_COUNT]; int[] run = new int[MAX_RUN_COUNT + 1];
int count = 0; run[0] = left; int count = 0; run[0] = left;
// Check if the array is nearly sorted // Check if the array is nearly sorted
@ -2076,7 +2076,7 @@ final class DualPivotQuicksort {
* Index run[i] is the start of i-th run * Index run[i] is the start of i-th run
* (ascending or descending sequence). * (ascending or descending sequence).
*/ */
int[] run = new int[MAX_RUN_COUNT]; int[] run = new int[MAX_RUN_COUNT + 1];
int count = 0; run[0] = left; int count = 0; run[0] = left;
// Check if the array is nearly sorted // Check if the array is nearly sorted
@ -2603,7 +2603,7 @@ final class DualPivotQuicksort {
* Index run[i] is the start of i-th run * Index run[i] is the start of i-th run
* (ascending or descending sequence). * (ascending or descending sequence).
*/ */
int[] run = new int[MAX_RUN_COUNT]; int[] run = new int[MAX_RUN_COUNT + 1];
int count = 0; run[0] = left; int count = 0; run[0] = left;
// Check if the array is nearly sorted // Check if the array is nearly sorted

View File

@ -23,7 +23,7 @@
/* /*
* @test * @test
* @bug 6880672 6896573 6899694 6976036 7013585 * @bug 6880672 6896573 6899694 6976036 7013585 7018258
* @summary Exercise Arrays.sort * @summary Exercise Arrays.sort
* @build Sorting * @build Sorting
* @run main Sorting -shortrun * @run main Sorting -shortrun
@ -66,7 +66,7 @@ public class Sorting {
} }
long end = System.currentTimeMillis(); long end = System.currentTimeMillis();
out.format("\nPASSED in %d sec.\n", Math.round((end - start) / 1E3)); out.format("PASSED in %d sec.\n", Math.round((end - start) / 1E3));
} }
private static void testAndCheck(int[] lengths, long[] randoms) { private static void testAndCheck(int[] lengths, long[] randoms) {
@ -78,46 +78,19 @@ public class Sorting {
testEmptyAndNullFloatArray(); testEmptyAndNullFloatArray();
testEmptyAndNullDoubleArray(); testEmptyAndNullDoubleArray();
for (long random : randoms) {
reset(random);
for (int length : lengths) { for (int length : lengths) {
testAndCheckWithInsertionSort(length, random); testMergeSort(length);
testAndCheckRange(length);
testAndCheckSubArray(length);
} }
reset(random); for (long seed : randoms) {
for (int length : lengths) { for (int length : lengths) {
testAndCheckWithCheckSum(length, random); testAndCheckWithInsertionSort(length, new MyRandom(seed));
} testAndCheckWithCheckSum(length, new MyRandom(seed));
reset(random); testAndCheckWithScrambling(length, new MyRandom(seed));
testAndCheckFloat(length, new MyRandom(seed));
for (int length : lengths) { testAndCheckDouble(length, new MyRandom(seed));
testAndCheckWithScrambling(length, random); testStable(length, new MyRandom(seed));
}
reset(random);
for (int length : lengths) {
testAndCheckFloat(length, random);
}
reset(random);
for (int length : lengths) {
testAndCheckDouble(length, random);
}
reset(random);
for (int length : lengths) {
testAndCheckRange(length, random);
}
reset(random);
for (int length : lengths) {
testAndCheckSubArray(length, random);
}
reset(random);
for (int length : lengths) {
testStable(length, random);
} }
} }
} }
@ -255,7 +228,7 @@ public class Sorting {
failed("Arrays.sort(double[]) shouldn't catch null array"); failed("Arrays.sort(double[]) shouldn't catch null array");
} }
private static void testAndCheckSubArray(int length, long random) { private static void testAndCheckSubArray(int length) {
ourDescription = "Check sorting of subarray"; ourDescription = "Check sorting of subarray";
int[] golden = new int[length]; int[] golden = new int[length];
boolean newLine = false; boolean newLine = false;
@ -282,7 +255,7 @@ public class Sorting {
} }
} }
private static void testAndCheckRange(int length, long random) { private static void testAndCheckRange(int length) {
ourDescription = "Check range check"; ourDescription = "Check range check";
int[] golden = new int[length]; int[] golden = new int[length];
@ -300,15 +273,16 @@ public class Sorting {
out.println(); out.println();
} }
private static void testStable(int length, long random) { private static void testStable(int length, MyRandom random) {
ourDescription = "Check if sorting is stable"; ourDescription = "Check if sorting is stable";
Pair[] a = build(length); Pair[] a = build(length, random);
out.println("Test 'stable': " + "random = " + random + out.println("Test 'stable': " + "random = " + random.getSeed() +
", length = " + length); ", length = " + length);
Arrays.sort(a); Arrays.sort(a);
checkSorted(a); checkSorted(a);
checkStable(a); checkStable(a);
out.println();
} }
private static void checkSorted(Pair[] a) { private static void checkSorted(Pair[] a) {
@ -342,11 +316,11 @@ public class Sorting {
} }
} }
private static Pair[] build(int length) { private static Pair[] build(int length, Random random) {
Pair[] a = new Pair[length * 4]; Pair[] a = new Pair[length * 4];
for (int i = 0; i < a.length; ) { for (int i = 0; i < a.length; ) {
int key = ourRandom.nextInt(); int key = random.nextInt();
a[i++] = new Pair(key, 1); a[i++] = new Pair(key, 1);
a[i++] = new Pair(key, 2); a[i++] = new Pair(key, 2);
a[i++] = new Pair(key, 3); a[i++] = new Pair(key, 3);
@ -389,7 +363,7 @@ public class Sorting {
} }
private static void testAndCheckWithInsertionSort(int length, long random) { private static void testAndCheckWithInsertionSort(int length, MyRandom random) {
if (length > 1000) { if (length > 1000) {
return; return;
} }
@ -398,13 +372,13 @@ public class Sorting {
for (int m = 1; m < 2 * length; m *= 2) { for (int m = 1; m < 2 * length; m *= 2) {
for (UnsortedBuilder builder : UnsortedBuilder.values()) { for (UnsortedBuilder builder : UnsortedBuilder.values()) {
builder.build(golden, m); builder.build(golden, m, random);
int[] test = golden.clone(); int[] test = golden.clone();
for (TypeConverter converter : TypeConverter.values()) { for (TypeConverter converter : TypeConverter.values()) {
out.println("Test 'insertion sort': " + converter + " " + out.println("Test 'insertion sort': " + converter +
builder + "random = " + random + ", length = " + " " + builder + "random = " + random.getSeed() +
length + ", m = " + m); ", length = " + length + ", m = " + m);
Object convertedGolden = converter.convert(golden); Object convertedGolden = converter.convert(golden);
Object convertedTest1 = converter.convert(test); Object convertedTest1 = converter.convert(test);
Object convertedTest2 = converter.convert(test); Object convertedTest2 = converter.convert(test);
@ -417,19 +391,44 @@ public class Sorting {
out.println(); out.println();
} }
private static void testAndCheckWithCheckSum(int length, long random) { private static void testMergeSort(int length) {
if (length < 1000) {
return;
}
ourDescription = "Check merge sorting";
int[] golden = new int[length];
int period = 67; // java.util.DualPivotQuicksort.MAX_RUN_COUNT
for (int m = period - 2; m <= period + 2; m++) {
for (MergeBuilder builder : MergeBuilder.values()) {
builder.build(golden, m);
int[] test = golden.clone();
for (TypeConverter converter : TypeConverter.values()) {
out.println("Test 'merge sort': " + converter + " " +
builder + "length = " + length + ", m = " + m);
Object convertedGolden = converter.convert(golden);
sort(convertedGolden);
checkSorted(convertedGolden);
}
}
}
out.println();
}
private static void testAndCheckWithCheckSum(int length, MyRandom random) {
ourDescription = "Check sorting with check sum"; ourDescription = "Check sorting with check sum";
int[] golden = new int[length]; int[] golden = new int[length];
for (int m = 1; m < 2 * length; m *= 2) { for (int m = 1; m < 2 * length; m *= 2) {
for (UnsortedBuilder builder : UnsortedBuilder.values()) { for (UnsortedBuilder builder : UnsortedBuilder.values()) {
builder.build(golden, m); builder.build(golden, m, random);
int[] test = golden.clone(); int[] test = golden.clone();
for (TypeConverter converter : TypeConverter.values()) { for (TypeConverter converter : TypeConverter.values()) {
out.println("Test 'check sum': " + converter + " " + out.println("Test 'check sum': " + converter +
builder + "random = " + random + ", length = " + " " + builder + "random = " + random.getSeed() +
length + ", m = " + m); ", length = " + length + ", m = " + m);
Object convertedGolden = converter.convert(golden); Object convertedGolden = converter.convert(golden);
Object convertedTest = converter.convert(test); Object convertedTest = converter.convert(test);
sort(convertedTest); sort(convertedTest);
@ -440,7 +439,7 @@ public class Sorting {
out.println(); out.println();
} }
private static void testAndCheckWithScrambling(int length, long random) { private static void testAndCheckWithScrambling(int length, MyRandom random) {
ourDescription = "Check sorting with scrambling"; ourDescription = "Check sorting with scrambling";
int[] golden = new int[length]; int[] golden = new int[length];
@ -451,12 +450,12 @@ public class Sorting {
for (SortedBuilder builder : SortedBuilder.values()) { for (SortedBuilder builder : SortedBuilder.values()) {
builder.build(golden, m); builder.build(golden, m);
int[] test = golden.clone(); int[] test = golden.clone();
scramble(test); scramble(test, random);
for (TypeConverter converter : TypeConverter.values()) { for (TypeConverter converter : TypeConverter.values()) {
out.println("Test 'scrambling': " + converter + " " + out.println("Test 'scrambling': " + converter +
builder + "random = " + random + ", length = " + " " + builder + "random = " + random.getSeed() +
length + ", m = " + m); ", length = " + length + ", m = " + m);
Object convertedGolden = converter.convert(golden); Object convertedGolden = converter.convert(golden);
Object convertedTest = converter.convert(test); Object convertedTest = converter.convert(test);
sort(convertedTest); sort(convertedTest);
@ -467,7 +466,7 @@ public class Sorting {
out.println(); out.println();
} }
private static void testAndCheckFloat(int length, long random) { private static void testAndCheckFloat(int length, MyRandom random) {
ourDescription = "Check float sorting"; ourDescription = "Check float sorting";
float[] golden = new float[length]; float[] golden = new float[length];
final int MAX = 10; final int MAX = 10;
@ -485,13 +484,12 @@ public class Sorting {
continue; continue;
} }
for (FloatBuilder builder : FloatBuilder.values()) { for (FloatBuilder builder : FloatBuilder.values()) {
out.println("Test 'float': random = " + random + out.println("Test 'float': random = " + random.getSeed() +
", length = " + length + ", a = " + a + ", length = " + length + ", a = " + a + ", g = " +
", g = " + g + ", z = " + z + ", n = " + n + g + ", z = " + z + ", n = " + n + ", p = " + p);
", p = " + p); builder.build(golden, a, g, z, n, p, random);
builder.build(golden, a, g, z, n, p);
float[] test = golden.clone(); float[] test = golden.clone();
scramble(test); scramble(test, random);
sort(test); sort(test);
compare(test, golden, a, n, g); compare(test, golden, a, n, g);
} }
@ -506,7 +504,7 @@ public class Sorting {
} }
} }
private static void testAndCheckDouble(int length, long random) { private static void testAndCheckDouble(int length, MyRandom random) {
ourDescription = "Check double sorting"; ourDescription = "Check double sorting";
double[] golden = new double[length]; double[] golden = new double[length];
final int MAX = 10; final int MAX = 10;
@ -524,12 +522,12 @@ public class Sorting {
continue; continue;
} }
for (DoubleBuilder builder : DoubleBuilder.values()) { for (DoubleBuilder builder : DoubleBuilder.values()) {
out.println("Test 'double': random = " + random + out.println("Test 'double': random = " + random.getSeed() +
", length = " + length + ", a = " + a + ", g = " + ", length = " + length + ", a = " + a + ", g = " +
g + ", z = " + z + ", n = " + n + ", p = " + p); g + ", z = " + z + ", n = " + n + ", p = " + p);
builder.build(golden, a, g, z, n, p); builder.build(golden, a, g, z, n, p, random);
double[] test = golden.clone(); double[] test = golden.clone();
scramble(test); scramble(test, random);
sort(test); sort(test);
compare(test, golden, a, n, g); compare(test, golden, a, n, g);
} }
@ -562,21 +560,21 @@ public class Sorting {
} }
} }
private static void scramble(int[] a) { private static void scramble(int[] a, Random random) {
for (int i = 0; i < a.length * 7; i++) { for (int i = 0; i < a.length * 7; i++) {
swap(a, ourRandom.nextInt(a.length), ourRandom.nextInt(a.length)); swap(a, random.nextInt(a.length), random.nextInt(a.length));
} }
} }
private static void scramble(float[] a) { private static void scramble(float[] a, Random random) {
for (int i = 0; i < a.length * 7; i++) { for (int i = 0; i < a.length * 7; i++) {
swap(a, ourRandom.nextInt(a.length), ourRandom.nextInt(a.length)); swap(a, random.nextInt(a.length), random.nextInt(a.length));
} }
} }
private static void scramble(double[] a) { private static void scramble(double[] a, Random random) {
for (int i = 0; i < a.length * 7; i++) { for (int i = 0; i < a.length * 7; i++) {
swap(a, ourRandom.nextInt(a.length), ourRandom.nextInt(a.length)); swap(a, random.nextInt(a.length), random.nextInt(a.length));
} }
} }
@ -689,10 +687,10 @@ public class Sorting {
private static enum FloatBuilder { private static enum FloatBuilder {
SIMPLE { SIMPLE {
void build(float[] x, int a, int g, int z, int n, int p) { void build(float[] x, int a, int g, int z, int n, int p, Random random) {
int fromIndex = 0; int fromIndex = 0;
float negativeValue = -ourRandom.nextFloat(); float negativeValue = -random.nextFloat();
float positiveValue = ourRandom.nextFloat(); float positiveValue = random.nextFloat();
writeValue(x, negativeValue, fromIndex, n); writeValue(x, negativeValue, fromIndex, n);
fromIndex += n; fromIndex += n;
@ -710,15 +708,15 @@ public class Sorting {
} }
}; };
abstract void build(float[] x, int a, int g, int z, int n, int p); abstract void build(float[] x, int a, int g, int z, int n, int p, Random random);
} }
private static enum DoubleBuilder { private static enum DoubleBuilder {
SIMPLE { SIMPLE {
void build(double[] x, int a, int g, int z, int n, int p) { void build(double[] x, int a, int g, int z, int n, int p, Random random) {
int fromIndex = 0; int fromIndex = 0;
double negativeValue = -ourRandom.nextFloat(); double negativeValue = -random.nextFloat();
double positiveValue = ourRandom.nextFloat(); double positiveValue = random.nextFloat();
writeValue(x, negativeValue, fromIndex, n); writeValue(x, negativeValue, fromIndex, n);
fromIndex += n; fromIndex += n;
@ -736,7 +734,7 @@ public class Sorting {
} }
}; };
abstract void build(double[] x, int a, int g, int z, int n, int p); abstract void build(double[] x, int a, int g, int z, int n, int p, Random random);
} }
private static void writeValue(float[] a, float value, int fromIndex, int count) { private static void writeValue(float[] a, float value, int fromIndex, int count) {
@ -812,7 +810,6 @@ public class Sorting {
} }
} }
}, },
ORGAN_PIPES { ORGAN_PIPES {
void build(int[] a, int m) { void build(int[] a, int m) {
int i = 0; int i = 0;
@ -841,37 +838,85 @@ public class Sorting {
} }
} }
private static enum MergeBuilder {
ASCENDING {
void build(int[] a, int m) {
int period = a.length / m;
int v = 1, i = 0;
for (int k = 0; k < m; k++) {
v = 1;
for (int p = 0; p < period; p++) {
a[i++] = v++;
}
}
for (int j = i; j < a.length - 1; j++) {
a[j] = v++;
}
a[a.length - 1] = 0;
}
},
DESCENDING {
void build(int[] a, int m) {
int period = a.length / m;
int v = -1, i = 0;
for (int k = 0; k < m; k++) {
v = -1;
for (int p = 0; p < period; p++) {
a[i++] = v--;
}
}
for (int j = i; j < a.length - 1; j++) {
a[j] = v--;
}
a[a.length - 1] = 0;
}
};
abstract void build(int[] a, int m);
@Override public String toString() {
String name = name();
for (int i = name.length(); i < 12; i++) {
name += " ";
}
return name;
}
}
private static enum UnsortedBuilder { private static enum UnsortedBuilder {
RANDOM { RANDOM {
void build(int[] a, int m) { void build(int[] a, int m, Random random) {
for (int i = 0; i < a.length; i++) { for (int i = 0; i < a.length; i++) {
a[i] = ourRandom.nextInt(); a[i] = random.nextInt();
} }
} }
}, },
ASCENDING { ASCENDING {
void build(int[] a, int m) { void build(int[] a, int m, Random random) {
for (int i = 0; i < a.length; i++) { for (int i = 0; i < a.length; i++) {
a[i] = m + i; a[i] = m + i;
} }
} }
}, },
DESCENDING { DESCENDING {
void build(int[] a, int m) { void build(int[] a, int m, Random random) {
for (int i = 0; i < a.length; i++) { for (int i = 0; i < a.length; i++) {
a[i] = a.length - m - i; a[i] = a.length - m - i;
} }
} }
}, },
ALL_EQUAL { ALL_EQUAL {
void build(int[] a, int m) { void build(int[] a, int m, Random random) {
for (int i = 0; i < a.length; i++) { for (int i = 0; i < a.length; i++) {
a[i] = m; a[i] = m;
} }
} }
}, },
SAW { SAW {
void build(int[] a, int m) { void build(int[] a, int m, Random random) {
int incCount = 1; int incCount = 1;
int decCount = a.length; int decCount = a.length;
int i = 0; int i = 0;
@ -897,21 +942,21 @@ public class Sorting {
} }
}, },
REPEATED { REPEATED {
void build(int[] a, int m) { void build(int[] a, int m, Random random) {
for (int i = 0; i < a.length; i++) { for (int i = 0; i < a.length; i++) {
a[i] = i % m; a[i] = i % m;
} }
} }
}, },
DUPLICATED { DUPLICATED {
void build(int[] a, int m) { void build(int[] a, int m, Random random) {
for (int i = 0; i < a.length; i++) { for (int i = 0; i < a.length; i++) {
a[i] = ourRandom.nextInt(m); a[i] = random.nextInt(m);
} }
} }
}, },
ORGAN_PIPES { ORGAN_PIPES {
void build(int[] a, int m) { void build(int[] a, int m, Random random) {
int middle = a.length / (m + 1); int middle = a.length / (m + 1);
for (int i = 0; i < middle; i++) { for (int i = 0; i < middle; i++) {
@ -923,28 +968,29 @@ public class Sorting {
} }
}, },
STAGGER { STAGGER {
void build(int[] a, int m) { void build(int[] a, int m, Random random) {
for (int i = 0; i < a.length; i++) { for (int i = 0; i < a.length; i++) {
a[i] = (i * m + i) % a.length; a[i] = (i * m + i) % a.length;
} }
} }
}, },
PLATEAU { PLATEAU {
void build(int[] a, int m) { void build(int[] a, int m, Random random) {
for (int i = 0; i < a.length; i++) { for (int i = 0; i < a.length; i++) {
a[i] = Math.min(i, m); a[i] = Math.min(i, m);
} }
} }
}, },
SHUFFLE { SHUFFLE {
void build(int[] a, int m) { void build(int[] a, int m, Random random) {
int x = 0, y = 0;
for (int i = 0; i < a.length; i++) { for (int i = 0; i < a.length; i++) {
a[i] = ourRandom.nextBoolean() ? (ourFirst += 2) : (ourSecond += 2); a[i] = random.nextBoolean() ? (x += 2) : (y += 2);
} }
} }
}; };
abstract void build(int[] a, int m); abstract void build(int[] a, int m, Random random);
@Override public String toString() { @Override public String toString() {
String name = name(); String name = name();
@ -1953,18 +1999,6 @@ public class Sorting {
} }
} }
private static void prepareRandom(int[] a) {
for (int i = 0; i < a.length; i++) {
a[i] = ourRandom.nextInt();
}
}
private static void reset(long seed) {
ourRandom = new Random(seed);
ourFirst = 0;
ourSecond = 0;
}
private static void outArray(Object[] a) { private static void outArray(Object[] a) {
for (int i = 0; i < a.length; i++) { for (int i = 0; i < a.length; i++) {
out.print(a[i] + " "); out.print(a[i] + " ");
@ -1993,8 +2027,18 @@ public class Sorting {
out.println(); out.println();
} }
private static int ourFirst; private static class MyRandom extends Random {
private static int ourSecond; MyRandom(long seed) {
private static Random ourRandom; super(seed);
mySeed = seed;
}
long getSeed() {
return mySeed;
}
private long mySeed;
}
private static String ourDescription; private static String ourDescription;
} }