Skip to content

Commit 737320b

Browse files
committed
Appendix rewrites
1 parent bc786ef commit 737320b

14 files changed

+148
-158
lines changed

lowlevel/AtomicEvenProducer.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33
// We make no guarantees that this code is fit for any purpose.
44
// Visit http://OnJava8.com for more book information.
55
// Atomic classes are occasionally useful in regular code
6-
// {IgnoreOutput} // No output validation
76
import java.util.concurrent.atomic.*;
87

98
public class AtomicEvenProducer extends IntGenerator {
@@ -17,3 +16,6 @@ public static void main(String[] args) {
1716
EvenChecker.test(new AtomicEvenProducer());
1817
}
1918
}
19+
/* Output:
20+
No odd numbers discovered
21+
*/

lowlevel/AtomicIntegerTest.java

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,9 @@ public void run() {
1717
evenIncrement();
1818
}
1919
public static void main(String[] args) {
20-
new TimedAbort(5); // Terminate after 5 seconds
21-
ExecutorService exec =
22-
Executors.newCachedThreadPool();
20+
new TimedAbort(4, "No failures discovered");
2321
AtomicIntegerTest ait = new AtomicIntegerTest();
24-
exec.execute(ait);
22+
CompletableFuture.runAsync(ait);
2523
while(true) {
2624
int val = ait.getValue();
2725
if(val % 2 != 0) {
@@ -32,5 +30,5 @@ public static void main(String[] args) {
3230
}
3331
}
3432
/* Output:
35-
TimedAbort 5
33+
No failures discovered
3634
*/

lowlevel/Atomicity.java

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,29 +13,32 @@ public class Atomicity {
1313
Compiled from "Atomicity.java"
1414
public class Atomicity {
1515
int i;
16+
1617
public Atomicity();
1718
Code:
1819
0: aload_0
19-
1: invokespecial #1 // Method
20+
1: invokespecial #1 // Method
2021
java/lang/Object."<init>":()V
2122
4: return
23+
2224
void f1();
2325
Code:
2426
0: aload_0
2527
1: dup
26-
2: getfield #2 // Field i:I
28+
2: getfield #2 // Field i:I
2729
5: iconst_1
2830
6: iadd
29-
7: putfield #2 // Field i:I
31+
7: putfield #2 // Field i:I
3032
10: return
33+
3134
void f2();
3235
Code:
3336
0: aload_0
3437
1: dup
35-
2: getfield #2 // Field i:I
38+
2: getfield #2 // Field i:I
3639
5: iconst_3
3740
6: iadd
38-
7: putfield #2 // Field i:I
41+
7: putfield #2 // Field i:I
3942
10: return
4043
}
4144
*/

lowlevel/AtomicityTest.java

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -17,20 +17,18 @@ public void run() {
1717
evenIncrement();
1818
}
1919
public static void main(String[] args) {
20-
new TimedAbort(4);
21-
ExecutorService es =
22-
Executors.newCachedThreadPool();
20+
new TimedAbort(4, "No failures found");
2321
AtomicityTest at = new AtomicityTest();
24-
es.execute(at);
22+
CompletableFuture.runAsync(at);
2523
while(true) {
2624
int val = at.getValue();
2725
if(val % 2 != 0) {
28-
System.out.println(val);
26+
System.out.println("failed with: " + val);
2927
System.exit(0);
3028
}
3129
}
3230
}
3331
}
3432
/* Output:
35-
1
33+
failed with: 21
3634
*/

lowlevel/AttemptLocking.java

Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -38,23 +38,20 @@ public static void main(String[] args) {
3838
final AttemptLocking al = new AttemptLocking();
3939
al.untimed(); // True -- lock is available
4040
al.timed(); // True -- lock is available
41-
// Now create a separate task to grab the lock:
42-
new Thread() {
43-
{ setDaemon(true); }
44-
@Override
45-
public void run() {
41+
// Now create a second task to grab the lock:
42+
CompletableFuture.runAsync( () -> {
4643
al.lock.lock();
4744
System.out.println("acquired");
48-
}
49-
}.start();
50-
new Nap(10); // Give the 2nd task a chance
45+
});
46+
new Nap(100); // Give the second task a chance
5147
al.untimed(); // False -- lock grabbed by task
5248
al.timed(); // False -- lock grabbed by task
5349
}
5450
}
5551
/* Output:
5652
tryLock(): true
5753
tryLock(2, TimeUnit.SECONDS): true
58-
tryLock(): true
59-
tryLock(2, TimeUnit.SECONDS): true
54+
acquired
55+
tryLock(): false
56+
tryLock(2, TimeUnit.SECONDS): false
6057
*/

lowlevel/DelayQueueDemo.java

Lines changed: 53 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,9 @@
22
// (c)2017 MindView LLC: see Copyright.txt
33
// We make no guarantees that this code is fit for any purpose.
44
// Visit http://OnJava8.com for more book information.
5-
import java.util.concurrent.*;
65
import java.util.*;
6+
import java.util.stream.*;
7+
import java.util.concurrent.*;
78
import static java.util.concurrent.TimeUnit.*;
89

910
class DelayedTask implements Runnable, Delayed {
@@ -12,7 +13,7 @@ class DelayedTask implements Runnable, Delayed {
1213
private final int delta;
1314
private final long trigger;
1415
protected static List<DelayedTask> sequence =
15-
new ArrayList<>();
16+
new CopyOnWriteArrayList<>();
1617
public DelayedTask(int delayInMilliseconds) {
1718
delta = delayInMilliseconds;
1819
trigger = System.nanoTime() +
@@ -32,74 +33,69 @@ public int compareTo(Delayed arg) {
3233
return 0;
3334
}
3435
@Override
35-
public void run() { System.out.print(this + " "); }
36+
public void run() {
37+
System.out.print(this + " ");
38+
}
3639
@Override
3740
public String toString() {
38-
return String.format("[%1$-4d]", delta) +
39-
" Task " + id;
41+
return
42+
String.format("[%d] Task %d", delta, id);
4043
}
4144
public String summary() {
42-
return "(" + id + ":" + delta + ")";
45+
return String.format("(%d:%d)", id, delta);
4346
}
44-
public static class EndSentinel extends DelayedTask {
45-
private ExecutorService exec;
46-
public EndSentinel(int delay, ExecutorService e) {
47-
super(delay);
48-
exec = e;
49-
}
47+
public static class EndTask extends DelayedTask {
48+
public EndTask(int delay) { super(delay); }
5049
@Override
5150
public void run() {
52-
for(DelayedTask pt : sequence) {
53-
System.out.print(pt.summary() + " ");
54-
}
55-
System.out.println();
56-
System.out.println(this + " Calling shutdownNow()");
57-
exec.shutdownNow();
58-
}
59-
}
60-
}
61-
62-
class DelayedTaskConsumer implements Runnable {
63-
private DelayQueue<DelayedTask> q;
64-
public DelayedTaskConsumer(DelayQueue<DelayedTask> q) {
65-
this.q = q;
66-
}
67-
@Override
68-
public void run() {
69-
try {
70-
while(!Thread.interrupted())
71-
q.take().run(); // Run task with current thread
72-
} catch(InterruptedException e) {
73-
// Acceptable way to exit
51+
sequence.forEach(dt ->
52+
System.out.println(dt.summary() + " "));
7453
}
75-
System.out.println("Finished DelayedTaskConsumer");
7654
}
7755
}
7856

7957
public class DelayQueueDemo {
80-
public static void main(String[] args) {
81-
SplittableRandom rand = new SplittableRandom(47);
82-
ExecutorService es = Executors.newCachedThreadPool();
83-
DelayQueue<DelayedTask> queue =
84-
new DelayQueue<>();
85-
// Fill with tasks that have random delays:
86-
for(int i = 0; i < 20; i++)
87-
queue.put(new DelayedTask(rand.nextInt(5000)));
88-
// Set the stopping point
89-
queue.add(new DelayedTask.EndSentinel(5000, es));
90-
es.execute(new DelayedTaskConsumer(queue));
58+
public static void
59+
main(String[] args) throws Exception {
60+
DelayQueue<DelayedTask> tasks =
61+
Stream.concat(
62+
// Tasks with random delays:
63+
new Random(47).ints(20, 0, 4000)
64+
.mapToObj(DelayedTask::new),
65+
// Add the summarizing task:
66+
Stream.of(
67+
new DelayedTask.EndTask(4000)))
68+
.collect(Collectors
69+
.toCollection(DelayQueue::new));
70+
DelayQueue<DelayedTask> delayQueue =
71+
new DelayQueue<>(tasks);
72+
while(delayQueue.size() > 0)
73+
delayQueue.take().run();
9174
}
9275
}
9376
/* Output:
94-
[70 ] Task 10 [125 ] Task 13 [267 ] Task 19 [635 ] Task 0
95-
[650 ] Task 16 [682 ] Task 17 [807 ] Task 11 [1131] Task 18
96-
[1177] Task 4 [1193] Task 9 [1634] Task 15 [1656] Task 6
97-
[2400] Task 12 [3479] Task 5 [3737] Task 1 [3768] Task 7
98-
[3941] Task 2 [4720] Task 3 [4762] Task 14 [4948] Task 8
99-
(0:635) (1:3737) (2:3941) (3:4720) (4:1177) (5:3479)
100-
(6:1656) (7:3768) (8:4948) (9:1193) (10:70) (11:807)
101-
(12:2400) (13:125) (14:4762) (15:1634) (16:650) (17:682)
102-
(18:1131) (19:267) (20:5000)
103-
[5000] Task 20 Calling shutdownNow()
104-
Finished DelayedTaskConsumer
77+
[128] Task 12 [429] Task 6 [551] Task 13 [555] Task 2 [693] Task 3 [809] Task 15
78+
[961] Task 5 [1258] Task 1 [1258] Task 20 [1520] Task 19 [1861] Task 4 [1998] T
79+
ask 17 [2200] Task 8 [2207] Task 10 [2288] Task 11 [2522] Task 9 [2589] Task 14
80+
[2861] Task 18 [2868] Task 7 [3278] Task 16 (0:4000)
81+
(1:1258)
82+
(2:555)
83+
(3:693)
84+
(4:1861)
85+
(5:961)
86+
(6:429)
87+
(7:2868)
88+
(8:2200)
89+
(9:2522)
90+
(10:2207)
91+
(11:2288)
92+
(12:128)
93+
(13:551)
94+
(14:2589)
95+
(15:809)
96+
(16:3278)
97+
(17:1998)
98+
(18:2861)
99+
(19:1520)
100+
(20:1258)
105101
*/

lowlevel/EvenChecker.java

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22
// (c)2017 MindView LLC: see Copyright.txt
33
// We make no guarantees that this code is fit for any purpose.
44
// Visit http://OnJava8.com for more book information.
5+
import java.util.*;
6+
import java.util.stream.*;
57
import java.util.concurrent.*;
68
import onjava.TimedAbort;
79

@@ -24,15 +26,16 @@ public void run() {
2426
}
2527
// Test any IntGenerator:
2628
public static void test(IntGenerator gp, int count) {
27-
System.out.println("Press Control-C to exit");
28-
ExecutorService es = Executors.newCachedThreadPool();
29-
for(int i = 0; i < count; i++)
30-
es.execute(new EvenChecker(gp, i));
31-
es.shutdown();
29+
List<CompletableFuture<Void>> checkers =
30+
IntStream.range(0, count)
31+
.mapToObj(i -> new EvenChecker(gp, i))
32+
.map(CompletableFuture::runAsync)
33+
.collect(Collectors.toList());
34+
checkers.forEach(CompletableFuture::join);
3235
}
3336
// Default value for count:
3437
public static void test(IntGenerator gp) {
35-
new TimedAbort(4);
38+
new TimedAbort(4, "No odd numbers discovered");
3639
test(gp, 10);
3740
}
3841
}

lowlevel/EvenProducer.java

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,10 @@ public static void main(String[] args) {
1717
}
1818
}
1919
/* Output:
20-
Press Control-C to exit
21-
841 not even!
22-
847 not even!
23-
845 not even!
24-
843 not even!
20+
1563 not even!
21+
1573 not even!
22+
1571 not even!
23+
1569 not even!
24+
1567 not even!
25+
1565 not even!
2526
*/

lowlevel/MutexEvenProducer.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33
// We make no guarantees that this code is fit for any purpose.
44
// Visit http://OnJava8.com for more book information.
55
// Preventing thread collisions with mutexes
6-
// {IgnoreOutput} // No output validation
76
import java.util.concurrent.locks.*;
87
import onjava.Nap;
98

@@ -26,3 +25,6 @@ public static void main(String[] args) {
2625
EvenChecker.test(new MutexEvenProducer());
2726
}
2827
}
28+
/*
29+
No odd numbers discovered
30+
*/

0 commit comments

Comments
 (0)