Skip to content

Commit 40d07cc

Browse files
committed
Moved code from book
Code from download was broken -- fixed that but discovered that code from book is different, so included that as well as the main file.
1 parent 03f8233 commit 40d07cc

4 files changed

Lines changed: 265 additions & 4 deletions

File tree

.gitignore

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,4 +50,8 @@ annotations/Test1.txt
5050
annotations/Test2.txt
5151
io/*.out
5252
io/*.txt
53+
io/*.dat
54+
io/*.tmp
5355
io/test.zip
56+
io/test.gz
57+
io/X.file

build.xml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,9 @@
1111
Ant available from: http://ant.apache.org/
1212

1313
To see options, type: ant -p
14+
15+
NOTE: Temporarily excluded
16+
annotations/build.xml
1417
</description>
1518

1619
<condition property="version1.8">
@@ -38,7 +41,6 @@
3841
io/build.xml
3942
xml/build.xml
4043
enumerated/build.xml
41-
annotations/build.xml
4244
concurrency/build.xml
4345
gui/build.xml
4446
swt/build.xml
Lines changed: 258 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,258 @@
1+
//: concurrency/SynchronizationComparisons.java
2+
// Comparing the performance of explicit Locks
3+
// and Atomics versus the synchronized keyword.
4+
import java.util.concurrent.*;
5+
import java.util.concurrent.atomic.*;
6+
import java.util.concurrent.locks.*;
7+
import java.util.*;
8+
import static net.mindview.util.Print.*;
9+
10+
abstract class Accumulator {
11+
public static long cycles = 50000L;
12+
// Number of Modifiers and Readers during each test:
13+
private static final int N = 4;
14+
public static ExecutorService exec =
15+
Executors.newFixedThreadPool(N*2);
16+
private static CyclicBarrier barrier =
17+
new CyclicBarrier(N*2 + 1);
18+
protected volatile int index = 0;
19+
protected volatile long value = 0;
20+
protected long duration = 0;
21+
protected String id = "error";
22+
protected final static int SIZE = 100000;
23+
protected static int[] preLoaded = new int[SIZE];
24+
static {
25+
// Load the array of random numbers:
26+
Random rand = new Random(47);
27+
for(int i = 0; i < SIZE; i++)
28+
preLoaded[i] = rand.nextInt();
29+
}
30+
public abstract void accumulate();
31+
public abstract long read();
32+
private class Modifier implements Runnable {
33+
public void run() {
34+
for(long i = 0; i < cycles; i++)
35+
accumulate();
36+
try {
37+
barrier.await();
38+
} catch(Exception e) {
39+
throw new RuntimeException(e);
40+
}
41+
}
42+
}
43+
private class Reader implements Runnable {
44+
private volatile long value;
45+
public void run() {
46+
for(long i = 0; i < cycles; i++)
47+
value = read();
48+
try {
49+
barrier.await();
50+
} catch(Exception e) {
51+
throw new RuntimeException(e);
52+
}
53+
}
54+
}
55+
public void timedTest() {
56+
long start = System.nanoTime();
57+
for(int i = 0; i < N; i++) {
58+
exec.execute(new Modifier());
59+
exec.execute(new Reader());
60+
}
61+
try {
62+
barrier.await();
63+
} catch(Exception e) {
64+
throw new RuntimeException(e);
65+
}
66+
duration = System.nanoTime() - start;
67+
printf("%-13s: %13d\n", id, duration);
68+
}
69+
public static void
70+
report(Accumulator acc1, Accumulator acc2) {
71+
printf("%-22s: %.2f\n", acc1.id + "/" + acc2.id,
72+
(double)acc1.duration/(double)acc2.duration);
73+
}
74+
}
75+
76+
class BaseLine extends Accumulator {
77+
{ id = "BaseLine"; }
78+
public void accumulate() {
79+
if(index >= SIZE - 1) index = 0;
80+
value += preLoaded[index++];
81+
}
82+
public long read() { return value; }
83+
}
84+
85+
class SynchronizedTest extends Accumulator {
86+
{ id = "synchronized"; }
87+
public synchronized void accumulate() {
88+
if(index >= SIZE - 1) index = 0;
89+
value += preLoaded[index++];
90+
}
91+
public synchronized long read() {
92+
return value;
93+
}
94+
}
95+
96+
class LockTest extends Accumulator {
97+
{ id = "Lock"; }
98+
private Lock lock = new ReentrantLock();
99+
public void accumulate() {
100+
lock.lock();
101+
try {
102+
if(index >= SIZE - 1) index = 0;
103+
value += preLoaded[index++];
104+
} finally {
105+
lock.unlock();
106+
}
107+
}
108+
public long read() {
109+
lock.lock();
110+
try {
111+
return value;
112+
} finally {
113+
lock.unlock();
114+
}
115+
}
116+
}
117+
118+
class AtomicTest extends Accumulator {
119+
{ id = "Atomic"; }
120+
private AtomicInteger index = new AtomicInteger(0);
121+
private AtomicLong value = new AtomicLong(0);
122+
public void accumulate() {
123+
// Oops! Relying on more than one Atomic at
124+
// a time doesn't work. But it still gives us
125+
// a performance indicator:
126+
int i = index.getAndIncrement();
127+
if(++i >= SIZE - 1) {
128+
i = 0;
129+
index.set(i);
130+
}
131+
value.getAndAdd(preLoaded[i]);
132+
}
133+
public long read() { return value.get(); }
134+
}
135+
136+
public class SynchronizationComparisons {
137+
static BaseLine baseLine = new BaseLine();
138+
static SynchronizedTest synch = new SynchronizedTest();
139+
static LockTest lock = new LockTest();
140+
static AtomicTest atomic = new AtomicTest();
141+
static void test() {
142+
print("============================");
143+
printf("%-12s : %13d\n", "Cycles", Accumulator.cycles);
144+
baseLine.timedTest();
145+
synch.timedTest();
146+
lock.timedTest();
147+
atomic.timedTest();
148+
Accumulator.report(synch, baseLine);
149+
Accumulator.report(lock, baseLine);
150+
Accumulator.report(atomic, baseLine);
151+
Accumulator.report(synch, lock);
152+
Accumulator.report(synch, atomic);
153+
Accumulator.report(lock, atomic);
154+
}
155+
public static void main(String[] args) {
156+
int iterations = 5; // Default
157+
if(args.length > 0) // Optionally change iterations
158+
iterations = new Integer(args[0]);
159+
// The first time fills the thread pool:
160+
print("Warmup");
161+
baseLine.timedTest();
162+
// Now the initial test doesn't include the cost
163+
// of starting the threads for the first time.
164+
// Produce multiple data points:
165+
for(int i = 0; i < iterations; i++) {
166+
test();
167+
Accumulator.cycles *= 2;
168+
}
169+
Accumulator.exec.shutdown();
170+
}
171+
} /* Output: (Sample)
172+
Warmup
173+
BaseLine : 34237033
174+
============================
175+
Cycles : 50000
176+
BaseLine : 20966632
177+
synchronized : 24326555
178+
Lock : 53669950
179+
Atomic : 30552487
180+
synchronized/BaseLine : 1.16
181+
Lock/BaseLine : 2.56
182+
Atomic/BaseLine : 1.46
183+
synchronized/Lock : 0.45
184+
synchronized/Atomic : 0.79
185+
Lock/Atomic : 1.76
186+
============================
187+
Cycles : 100000
188+
BaseLine : 41512818
189+
synchronized : 43843003
190+
Lock : 87430386
191+
Atomic : 51892350
192+
synchronized/BaseLine : 1.06
193+
Lock/BaseLine : 2.11
194+
Atomic/BaseLine : 1.25
195+
synchronized/Lock : 0.50
196+
synchronized/Atomic : 0.84
197+
Lock/Atomic : 1.68
198+
============================
199+
Cycles : 200000
200+
BaseLine : 80176670
201+
synchronized : 5455046661
202+
Lock : 177686829
203+
Atomic : 101789194
204+
synchronized/BaseLine : 68.04
205+
Lock/BaseLine : 2.22
206+
Atomic/BaseLine : 1.27
207+
synchronized/Lock : 30.70
208+
synchronized/Atomic : 53.59
209+
Lock/Atomic : 1.75
210+
============================
211+
Cycles : 400000
212+
BaseLine : 160383513
213+
synchronized : 780052493
214+
Lock : 362187652
215+
Atomic : 202030984
216+
synchronized/BaseLine : 4.86
217+
Lock/BaseLine : 2.26
218+
Atomic/BaseLine : 1.26
219+
synchronized/Lock : 2.15
220+
synchronized/Atomic : 3.86
221+
Lock/Atomic : 1.79
222+
============================
223+
Cycles : 800000
224+
BaseLine : 322064955
225+
synchronized : 336155014
226+
Lock : 704615531
227+
Atomic : 393231542
228+
synchronized/BaseLine : 1.04
229+
Lock/BaseLine : 2.19
230+
Atomic/BaseLine : 1.22
231+
synchronized/Lock : 0.47
232+
synchronized/Atomic : 0.85
233+
Lock/Atomic : 1.79
234+
============================
235+
Cycles : 1600000
236+
BaseLine : 650004120
237+
synchronized : 52235762925
238+
Lock : 1419602771
239+
Atomic : 796950171
240+
synchronized/BaseLine : 80.36
241+
Lock/BaseLine : 2.18
242+
Atomic/BaseLine : 1.23
243+
synchronized/Lock : 36.80
244+
synchronized/Atomic : 65.54
245+
Lock/Atomic : 1.78
246+
============================
247+
Cycles : 3200000
248+
BaseLine : 1285664519
249+
synchronized : 96336767661
250+
Lock : 2846988654
251+
Atomic : 1590545726
252+
synchronized/BaseLine : 74.93
253+
Lock/BaseLine : 2.21
254+
Atomic/BaseLine : 1.24
255+
synchronized/Lock : 33.84
256+
synchronized/Atomic : 60.57
257+
Lock/Atomic : 1.79
258+
*///:~

io/build.xml

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -136,7 +136,6 @@
136136
failonerror="true"
137137
fork="true">
138138
<arg line='"D.*\.java"'/>
139-
140139
</java>
141140
</target>
142141

@@ -148,7 +147,6 @@
148147
failonerror="true"
149148
fork="true">
150149
<arg line='"D.*\.java"'/>
151-
152150
</java>
153151
</target>
154152

@@ -160,7 +158,6 @@
160158
failonerror="true"
161159
fork="true">
162160
<arg line='"D.*\.java"'/>
163-
164161
</java>
165162
</target>
166163

0 commit comments

Comments
 (0)