Code from book
Also added some 5-second timeouts in various places to build.xml because (expected) exceptions were causing ant to hang for a long time, then inexplicably continue.
This commit is contained in:
parent
40d07cccc4
commit
efd9f6d36b
@ -21,8 +21,7 @@ abstract class Accumulator {
|
|||||||
protected String id = "error";
|
protected String id = "error";
|
||||||
protected final static int SIZE = 100000;
|
protected final static int SIZE = 100000;
|
||||||
protected static int[] preLoaded = new int[SIZE];
|
protected static int[] preLoaded = new int[SIZE];
|
||||||
static {
|
static { // Load the array of random numbers:
|
||||||
// Load the array of random numbers:
|
|
||||||
Random rand = new Random(47);
|
Random rand = new Random(47);
|
||||||
for(int i = 0; i < SIZE; i++)
|
for(int i = 0; i < SIZE; i++)
|
||||||
preLoaded[i] = rand.nextInt();
|
preLoaded[i] = rand.nextInt();
|
||||||
@ -66,24 +65,14 @@ abstract class Accumulator {
|
|||||||
duration = System.nanoTime() - start;
|
duration = System.nanoTime() - start;
|
||||||
printf("%-13s: %13d\n", id, duration);
|
printf("%-13s: %13d\n", id, duration);
|
||||||
}
|
}
|
||||||
public static void
|
public void report(Accumulator acc2) {
|
||||||
report(Accumulator acc1, Accumulator acc2) {
|
printf("%-22s: %.2f\n", this.id + "/" + acc2.id,
|
||||||
printf("%-22s: %.2f\n", acc1.id + "/" + acc2.id,
|
(double)this.duration/(double)acc2.duration);
|
||||||
(double)acc1.duration/(double)acc2.duration);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class BaseLine extends Accumulator {
|
|
||||||
{ id = "BaseLine"; }
|
|
||||||
public void accumulate() {
|
|
||||||
value += preLoaded[index++];
|
|
||||||
if(index >= SIZE) index = 0;
|
|
||||||
}
|
|
||||||
public long read() { return value; }
|
|
||||||
}
|
|
||||||
|
|
||||||
class SynchronizedTest extends Accumulator {
|
class SynchronizedTest extends Accumulator {
|
||||||
{ id = "synchronized"; }
|
{ id = "synch"; }
|
||||||
public synchronized void accumulate() {
|
public synchronized void accumulate() {
|
||||||
value += preLoaded[index++];
|
value += preLoaded[index++];
|
||||||
if(index >= SIZE) index = 0;
|
if(index >= SIZE) index = 0;
|
||||||
@ -119,36 +108,36 @@ class AtomicTest extends Accumulator {
|
|||||||
{ id = "Atomic"; }
|
{ id = "Atomic"; }
|
||||||
private AtomicInteger index = new AtomicInteger(0);
|
private AtomicInteger index = new AtomicInteger(0);
|
||||||
private AtomicLong value = new AtomicLong(0);
|
private AtomicLong value = new AtomicLong(0);
|
||||||
public void accumulate() {
|
// Relying on more than one Atomic at a time doesn't
|
||||||
// Oops! Relying on more than one Atomic at
|
// work, so we still have to synchronize. But it gives
|
||||||
// a time doesn't work. But it still gives us
|
// a performance indicator:
|
||||||
// a performance indicator:
|
public synchronized void accumulate() {
|
||||||
int i = index.getAndIncrement();
|
int i;
|
||||||
|
i = index.getAndIncrement();
|
||||||
value.getAndAdd(preLoaded[i]);
|
value.getAndAdd(preLoaded[i]);
|
||||||
if(++i >= SIZE)
|
if(++i >= SIZE)
|
||||||
index.set(0);
|
index.set(0);
|
||||||
}
|
}
|
||||||
public long read() { return value.get(); }
|
public synchronized long read() { return value.get(); }
|
||||||
|
public void report(Accumulator acc2) {
|
||||||
|
printf("%-22s: %.2f\n", "synch/(Atomic-synch)",
|
||||||
|
(double)acc2.duration/
|
||||||
|
((double)this.duration - (double)acc2.duration));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public class SynchronizationComparisons {
|
public class SynchronizationComparisons {
|
||||||
static BaseLine baseLine = new BaseLine();
|
|
||||||
static SynchronizedTest synch = new SynchronizedTest();
|
static SynchronizedTest synch = new SynchronizedTest();
|
||||||
static LockTest lock = new LockTest();
|
static LockTest lock = new LockTest();
|
||||||
static AtomicTest atomic = new AtomicTest();
|
static AtomicTest atomic = new AtomicTest();
|
||||||
static void test() {
|
static void test() {
|
||||||
print("============================");
|
print("============================");
|
||||||
printf("%-12s : %13d\n", "Cycles", Accumulator.cycles);
|
printf("%-12s : %13d\n", "Cycles", Accumulator.cycles);
|
||||||
baseLine.timedTest();
|
|
||||||
synch.timedTest();
|
synch.timedTest();
|
||||||
lock.timedTest();
|
lock.timedTest();
|
||||||
atomic.timedTest();
|
atomic.timedTest();
|
||||||
Accumulator.report(synch, baseLine);
|
synch.report(lock);
|
||||||
Accumulator.report(lock, baseLine);
|
atomic.report(synch);
|
||||||
Accumulator.report(atomic, baseLine);
|
|
||||||
Accumulator.report(synch, lock);
|
|
||||||
Accumulator.report(synch, atomic);
|
|
||||||
Accumulator.report(lock, atomic);
|
|
||||||
}
|
}
|
||||||
public static void main(String[] args) {
|
public static void main(String[] args) {
|
||||||
int iterations = 5; // Default
|
int iterations = 5; // Default
|
||||||
@ -156,7 +145,7 @@ public class SynchronizationComparisons {
|
|||||||
iterations = new Integer(args[0]);
|
iterations = new Integer(args[0]);
|
||||||
// The first time fills the thread pool:
|
// The first time fills the thread pool:
|
||||||
print("Warmup");
|
print("Warmup");
|
||||||
baseLine.timedTest();
|
synch.timedTest();
|
||||||
// Now the initial test doesn't include the cost
|
// Now the initial test doesn't include the cost
|
||||||
// of starting the threads for the first time.
|
// of starting the threads for the first time.
|
||||||
// Produce multiple data points:
|
// Produce multiple data points:
|
||||||
@ -166,91 +155,42 @@ public class SynchronizationComparisons {
|
|||||||
}
|
}
|
||||||
Accumulator.exec.shutdown();
|
Accumulator.exec.shutdown();
|
||||||
}
|
}
|
||||||
} /* Output: (Sample)
|
} /* Output: (Sample) using JDK6u10
|
||||||
Warmup
|
Warmup
|
||||||
BaseLine : 34237033
|
synch : 129868038
|
||||||
============================
|
============================
|
||||||
Cycles : 50000
|
Cycles : 50000
|
||||||
BaseLine : 20966632
|
synch : 126407922
|
||||||
synchronized : 24326555
|
Lock : 51207369
|
||||||
Lock : 53669950
|
Atomic : 141845223
|
||||||
Atomic : 30552487
|
synch/Lock : 2.47
|
||||||
synchronized/BaseLine : 1.16
|
synch/(Atomic-synch) : 8.19
|
||||||
Lock/BaseLine : 2.56
|
|
||||||
Atomic/BaseLine : 1.46
|
|
||||||
synchronized/Lock : 0.45
|
|
||||||
synchronized/Atomic : 0.79
|
|
||||||
Lock/Atomic : 1.76
|
|
||||||
============================
|
============================
|
||||||
Cycles : 100000
|
Cycles : 100000
|
||||||
BaseLine : 41512818
|
synch : 251174061
|
||||||
synchronized : 43843003
|
Lock : 105338114
|
||||||
Lock : 87430386
|
Atomic : 279503250
|
||||||
Atomic : 51892350
|
synch/Lock : 2.38
|
||||||
synchronized/BaseLine : 1.06
|
synch/(Atomic-synch) : 8.87
|
||||||
Lock/BaseLine : 2.11
|
|
||||||
Atomic/BaseLine : 1.25
|
|
||||||
synchronized/Lock : 0.50
|
|
||||||
synchronized/Atomic : 0.84
|
|
||||||
Lock/Atomic : 1.68
|
|
||||||
============================
|
============================
|
||||||
Cycles : 200000
|
Cycles : 200000
|
||||||
BaseLine : 80176670
|
synch : 508778006
|
||||||
synchronized : 5455046661
|
Lock : 214398402
|
||||||
Lock : 177686829
|
Atomic : 574464795
|
||||||
Atomic : 101789194
|
synch/Lock : 2.37
|
||||||
synchronized/BaseLine : 68.04
|
synch/(Atomic-synch) : 7.75
|
||||||
Lock/BaseLine : 2.22
|
|
||||||
Atomic/BaseLine : 1.27
|
|
||||||
synchronized/Lock : 30.70
|
|
||||||
synchronized/Atomic : 53.59
|
|
||||||
Lock/Atomic : 1.75
|
|
||||||
============================
|
============================
|
||||||
Cycles : 400000
|
Cycles : 400000
|
||||||
BaseLine : 160383513
|
synch : 1027003521
|
||||||
synchronized : 780052493
|
Lock : 428342577
|
||||||
Lock : 362187652
|
Atomic : 1115667617
|
||||||
Atomic : 202030984
|
synch/Lock : 2.40
|
||||||
synchronized/BaseLine : 4.86
|
synch/(Atomic-synch) : 11.58
|
||||||
Lock/BaseLine : 2.26
|
|
||||||
Atomic/BaseLine : 1.26
|
|
||||||
synchronized/Lock : 2.15
|
|
||||||
synchronized/Atomic : 3.86
|
|
||||||
Lock/Atomic : 1.79
|
|
||||||
============================
|
============================
|
||||||
Cycles : 800000
|
Cycles : 800000
|
||||||
BaseLine : 322064955
|
synch : 2179255097
|
||||||
synchronized : 336155014
|
Lock : 877216314
|
||||||
Lock : 704615531
|
Atomic : 2371504710
|
||||||
Atomic : 393231542
|
synch/Lock : 2.48
|
||||||
synchronized/BaseLine : 1.04
|
synch/(Atomic-synch) : 11.34
|
||||||
Lock/BaseLine : 2.19
|
|
||||||
Atomic/BaseLine : 1.22
|
|
||||||
synchronized/Lock : 0.47
|
|
||||||
synchronized/Atomic : 0.85
|
|
||||||
Lock/Atomic : 1.79
|
|
||||||
============================
|
|
||||||
Cycles : 1600000
|
|
||||||
BaseLine : 650004120
|
|
||||||
synchronized : 52235762925
|
|
||||||
Lock : 1419602771
|
|
||||||
Atomic : 796950171
|
|
||||||
synchronized/BaseLine : 80.36
|
|
||||||
Lock/BaseLine : 2.18
|
|
||||||
Atomic/BaseLine : 1.23
|
|
||||||
synchronized/Lock : 36.80
|
|
||||||
synchronized/Atomic : 65.54
|
|
||||||
Lock/Atomic : 1.78
|
|
||||||
============================
|
|
||||||
Cycles : 3200000
|
|
||||||
BaseLine : 1285664519
|
|
||||||
synchronized : 96336767661
|
|
||||||
Lock : 2846988654
|
|
||||||
Atomic : 1590545726
|
|
||||||
synchronized/BaseLine : 74.93
|
|
||||||
Lock/BaseLine : 2.21
|
|
||||||
Atomic/BaseLine : 1.24
|
|
||||||
synchronized/Lock : 33.84
|
|
||||||
synchronized/Atomic : 60.57
|
|
||||||
Lock/Atomic : 1.79
|
|
||||||
*///:~
|
*///:~
|
||||||
|
@ -142,8 +142,10 @@
|
|||||||
classname="CaptureUncaughtException"
|
classname="CaptureUncaughtException"
|
||||||
classpath="${java.class.path};${basedir};${basedir}/.."
|
classpath="${java.class.path};${basedir};${basedir}/.."
|
||||||
dir="../concurrency/"
|
dir="../concurrency/"
|
||||||
failonerror="true"
|
failonerror="false"
|
||||||
fork="true"/>
|
fork="true"
|
||||||
|
timeout="5000"
|
||||||
|
/>
|
||||||
</target>
|
</target>
|
||||||
|
|
||||||
<target name="CarBuilder">
|
<target name="CarBuilder">
|
||||||
@ -244,7 +246,8 @@
|
|||||||
classpath="${java.class.path};${basedir};${basedir}/.."
|
classpath="${java.class.path};${basedir};${basedir}/.."
|
||||||
dir="../concurrency/"
|
dir="../concurrency/"
|
||||||
failonerror="false"
|
failonerror="false"
|
||||||
fork="true"/>
|
fork="true"
|
||||||
|
timeout="5000" />
|
||||||
<echo message="* Exception was expected *"/>
|
<echo message="* Exception was expected *"/>
|
||||||
</target>
|
</target>
|
||||||
|
|
||||||
@ -417,7 +420,8 @@
|
|||||||
classpath="${java.class.path};${basedir};${basedir}/.."
|
classpath="${java.class.path};${basedir};${basedir}/.."
|
||||||
dir="../concurrency/"
|
dir="../concurrency/"
|
||||||
failonerror="false"
|
failonerror="false"
|
||||||
fork="true"/>
|
fork="true"
|
||||||
|
timeout="5000"/>
|
||||||
<echo message="* Exception was expected *"/>
|
<echo message="* Exception was expected *"/>
|
||||||
</target>
|
</target>
|
||||||
|
|
||||||
@ -527,8 +531,9 @@
|
|||||||
classname="SettingDefaultHandler"
|
classname="SettingDefaultHandler"
|
||||||
classpath="${java.class.path};${basedir};${basedir}/.."
|
classpath="${java.class.path};${basedir};${basedir}/.."
|
||||||
dir="../concurrency/"
|
dir="../concurrency/"
|
||||||
failonerror="true"
|
failonerror="false"
|
||||||
fork="true"/>
|
fork="true"
|
||||||
|
timeout="5000"/>
|
||||||
</target>
|
</target>
|
||||||
|
|
||||||
<target name="SimpleDaemons">
|
<target name="SimpleDaemons">
|
||||||
|
Loading…
x
Reference in New Issue
Block a user