Moved examples from "Concurrent" to "lowlevel"

This commit is contained in:
Bruce Eckel 2016-12-25 12:36:49 -08:00
parent c590aeb851
commit afa51c5b7a
27 changed files with 626 additions and 234 deletions

31
concurrent/Baked.java Normal file
View File

@ -0,0 +1,31 @@
// concurrent/Baked.java
// (c)2016 MindView LLC: see Copyright.txt
// We make no guarantees that this code is fit for any purpose.
// Visit http://OnJava8.com for more book information.
import java.util.concurrent.*;
import java.util.stream.*;
import onjava.Nap;
public class Baked {
static class Pan {}
static Pan pan(Batter b) {
new Nap(100);
return new Pan();
}
static Baked heat(Pan p) {
new Nap(100);
return new Baked();
}
static CompletableFuture<Baked>
bake(CompletableFuture<Batter> cfb) {
return cfb
.thenApplyAsync(Baked::pan)
.thenApplyAsync(Baked::heat);
}
public static
Stream<CompletableFuture<Baked>> batch() {
CompletableFuture<Batter> batter = Batter.mix();
return Stream.of(bake(batter), bake(batter),
bake(batter), bake(batter));
}
}

34
concurrent/Batter.java Normal file
View File

@ -0,0 +1,34 @@
// concurrent/Batter.java
// (c)2016 MindView LLC: see Copyright.txt
// We make no guarantees that this code is fit for any purpose.
// Visit http://OnJava8.com for more book information.
import java.util.concurrent.*;
import onjava.Nap;
public class Batter {
static class Eggs {}
static class Milk {}
static class Sugar {}
static class Flour {}
static <T> T prepare(T ingredient) {
new Nap(100);
return ingredient;
}
static <T> CompletableFuture<T> cf(T ingredient) {
return CompletableFuture
.completedFuture(ingredient)
.thenApply(Batter::prepare);
}
public static CompletableFuture<Batter> mix() {
CompletableFuture<Eggs> eggs = cf(new Eggs());
CompletableFuture<Milk> milk = cf(new Milk());
CompletableFuture<Sugar> sugar = cf(new Sugar());
CompletableFuture<Flour> flour = cf(new Flour());
CompletableFuture
.allOf(eggs, milk, sugar, flour)
.join();
new Nap(100); // Mixing time
return
CompletableFuture.completedFuture(new Batter());
}
}

26
concurrent/Breakable.java Normal file
View File

@ -0,0 +1,26 @@
// concurrent/Breakable.java
// (c)2016 MindView LLC: see Copyright.txt
// We make no guarantees that this code is fit for any purpose.
// Visit http://OnJava8.com for more book information.
import java.util.concurrent.*;
public class Breakable {
String id;
private int failcount;
public Breakable(String id, int failcount) {
this.id = id;
this.failcount = failcount;
}
@Override
public String toString() {
return "Breakable_" + id +
" [" + failcount + "]";
}
public static Breakable work(Breakable b) {
if(--b.failcount == 0)
throw new RuntimeException(
"Breakable_" + b.id + " failed");
System.out.println(b);
return b;
}
}

View File

@ -0,0 +1,79 @@
// concurrent/CatchCompletableExceptions.java
// (c)2016 MindView LLC: see Copyright.txt
// We make no guarantees that this code is fit for any purpose.
// Visit http://OnJava8.com for more book information.
import java.util.concurrent.*;
import onjava.Nap;
public class CatchCompletableExceptions {
static void handleException(int failcount) {
// Call Function only if there's an exception,
// Must produce same type as came in:
CompletableExceptions
.test("exceptionally", failcount)
.exceptionally((ex) -> { // Function
if(ex == null)
System.out.println("I don't get it yet");
return new Breakable(ex.getMessage(), 0);
})
.thenAccept(str ->
System.out.println("result: " + str));
// Create a new result (recover):
CompletableExceptions
.test("handle", failcount)
.handle((result, fail) -> { // BiFunction
if(fail != null)
return "Failure recovery object";
else
return result + " is good";
})
.thenAccept(str ->
System.out.println("result: " + str));
// Do something but pass the same result through:
CompletableExceptions
.test("whenComplete", failcount)
.whenComplete((result, fail) -> { // BiConsumer
if(fail != null)
System.out.println("It failed");
else
System.out.println(result + " OK");
})
.thenAccept(r ->
System.out.println("result: " + r));
}
public static void main(String[] args) {
System.out.println("**** Failure Mode ****");
handleException(2);
System.out.println("**** Success Mode ****");
handleException(0);
}
}
/* Output:
**** Failure Mode ****
Breakable_exceptionally [1]
result: Breakable_java.lang.RuntimeException:
Breakable_exceptionally failed [0]
Breakable_handle [1]
result: Failure recovery object
Breakable_whenComplete [1]
It failed
**** Success Mode ****
Breakable_exceptionally [-1]
Breakable_exceptionally [-2]
Breakable_exceptionally [-3]
Breakable_exceptionally [-4]
result: Breakable_exceptionally [-4]
Breakable_handle [-1]
Breakable_handle [-2]
Breakable_handle [-3]
Breakable_handle [-4]
result: Breakable_handle [-4] is good
Breakable_whenComplete [-1]
Breakable_whenComplete [-2]
Breakable_whenComplete [-3]
Breakable_whenComplete [-4]
Breakable_whenComplete [-4] OK
result: Breakable_whenComplete [-4]
*/

View File

@ -1,19 +0,0 @@
// concurrent/Chopstick.java
// (c)2016 MindView LLC: see Copyright.txt
// We make no guarantees that this code is fit for any purpose.
// Visit http://OnJava8.com for more book information.
// Chopsticks for dining philosophers
public class Chopstick {
private boolean taken = false;
public synchronized
void take() throws InterruptedException {
while(taken)
wait();
taken = true;
}
public synchronized void drop() {
taken = false;
notifyAll();
}
}

View File

@ -19,3 +19,9 @@ public class CompletableApply {
cf4.thenApply(Machina::work);
}
}
/* Output:
Machina0: ONE
Machina0: TWO
Machina0: THREE
Machina0: complete
*/

View File

@ -0,0 +1,69 @@
// concurrent/CompletableExceptions.java
// (c)2016 MindView LLC: see Copyright.txt
// We make no guarantees that this code is fit for any purpose.
// Visit http://OnJava8.com for more book information.
import java.util.concurrent.*;
import onjava.Nap;
public class CompletableExceptions {
static CompletableFuture<Breakable>
test(String id, int failcount) {
return
CompletableFuture.completedFuture(
new Breakable(id, failcount))
.thenApply(Breakable::work)
.thenApply(Breakable::work)
.thenApply(Breakable::work)
.thenApply(Breakable::work);
}
public static void main(String[] args) {
// Exceptions don't appear ...
test("A", 1);
test("B", 2);
test("C", 3);
test("D", 4);
test("E", 5);
// ... until you try to fetch the value:
try {
test("F", 2).get(); // or join()
} catch(Exception e) {
System.out.println(e.getMessage());
}
// Test for exceptions:
System.out.println(
test("G", 2).isCompletedExceptionally());
// Counts as "done":
System.out.println(test("H", 2).isDone());
// Force an exception:
CompletableFuture<Integer> cfi =
new CompletableFuture<>();
System.out.println("done? " + cfi.isDone());
cfi.completeExceptionally(
new RuntimeException("forced"));
try {
cfi.get();
} catch(Exception e) {
System.out.println(e.getMessage());
}
}
}
/* Output:
Breakable_B [1]
Breakable_C [2]
Breakable_C [1]
Breakable_D [3]
Breakable_D [2]
Breakable_D [1]
Breakable_E [4]
Breakable_E [3]
Breakable_E [2]
Breakable_E [1]
Breakable_F [1]
java.lang.RuntimeException: Breakable_F failed
Breakable_G [1]
true
Breakable_H [1]
true
done? false
java.lang.RuntimeException: forced
*/

View File

@ -5,10 +5,10 @@
import java.util.concurrent.*;
public class CompletableOperations {
static CompletableFuture<Integer> cfi() {
static CompletableFuture<Integer> cfi(int i) {
return
CompletableFuture.completedFuture(
new Integer(1));
new Integer(i));
}
// Get and show value stored in a CF:
static void showr(CompletableFuture<Integer> c) {
@ -29,11 +29,60 @@ public class CompletableOperations {
}
}
public static void main(String[] args) {
showr(cfi()); // Basic test
showr(cfi().thenApplyAsync(i -> i + 42));
voidr(cfi().runAsync(() -> System.out.println("run")));
CompletableFuture<Integer> c = cfi();
showr(cfi(1)); // Basic test
voidr(cfi(2).runAsync(() ->
System.out.println("runAsync")));
voidr(cfi(3).thenRunAsync(() ->
System.out.println("thenRunAsync")));
showr(CompletableFuture.supplyAsync(() -> 99));
voidr(cfi(4).thenAcceptAsync(i ->
System.out.println("thenAcceptAsync: " + i)));
showr(cfi(5).thenApplyAsync(i -> i + 42));
showr(cfi(6).thenComposeAsync(i -> cfi(i + 99)));
CompletableFuture<Integer> c = cfi(7);
c.obtrudeValue(111);
showr(c);
showr(cfi(8).toCompletableFuture());
c = new CompletableFuture<>();
c.complete(9);
showr(c);
c = new CompletableFuture<>();
c.cancel(true);
System.out.println("cancelled: " +
c.isCancelled());
System.out.println("completed exceptionally: " +
c.isCompletedExceptionally());
System.out.println("done: " + c.isDone());
System.out.println(c);
c = new CompletableFuture<>();
System.out.println(c.getNow(777));
c = new CompletableFuture<>();
c.thenApplyAsync(i -> i + 42)
.thenApplyAsync(i -> i * 12);
System.out.println("dependents: " +
c.getNumberOfDependents());
c.thenApplyAsync(i -> i / 2);
System.out.println("dependents: " +
c.getNumberOfDependents());
}
}
/* Output:
1
runAsync
thenRunAsync
99
thenAcceptAsync: 4
47
105
111
8
9
cancelled: true
completed exceptionally: true
done: true
java.util.concurrent.CompletableFuture@404b9385[Completed
exceptionally]
777
dependents: 1
dependents: 2
*/

View File

@ -42,4 +42,47 @@ public class CompletablePizza {
}
}
/* Output:
/* Output:
56
Pizza 0: ROLLED
Pizza 1: ROLLED
Pizza 4: ROLLED
Pizza 2: ROLLED
Pizza 3: ROLLED
Pizza 0: SAUCED
Pizza 3: SAUCED
Pizza 2: SAUCED
Pizza 4: SAUCED
Pizza 1: SAUCED
Pizza 0: CHEESED
Pizza 4: CHEESED
Pizza 2: CHEESED
Pizza 3: CHEESED
Pizza 1: CHEESED
Pizza 0: TOPPED
Pizza 4: TOPPED
Pizza 1: TOPPED
Pizza 3: TOPPED
Pizza 2: TOPPED
Pizza 0: BAKED
Pizza 4: BAKED
Pizza 3: BAKED
Pizza 1: BAKED
Pizza 2: BAKED
Pizza 0: SLICED
Pizza 2: SLICED
Pizza 4: SLICED
Pizza 1: SLICED
Pizza 3: SLICED
Pizza 0: BOXED
Pizza0: complete
Pizza 4: BOXED
Pizza 3: BOXED
Pizza 2: BOXED
Pizza 1: BOXED
Pizza1: complete
Pizza2: complete
Pizza3: complete
Pizza4: complete
1659
*/

View File

@ -1,60 +0,0 @@
// concurrent/DeadlockingDiningPhilosophers.java
// (c)2016 MindView LLC: see Copyright.txt
// We make no guarantees that this code is fit for any purpose.
// Visit http://OnJava8.com for more book information.
// Demonstrates how deadlock can be hidden in a program
// {java DeadlockingDiningPhilosophers 0 5 timeout}
import java.util.concurrent.*;
import onjava.Nap;
public class DeadlockingDiningPhilosophers {
public static void main(String[] args) {
int ponder = 5;
if(args.length > 0)
ponder = Integer.parseInt(args[0]);
int size = 5;
if(args.length > 1)
size = Integer.parseInt(args[1]);
ExecutorService es = Executors.newCachedThreadPool();
Chopstick[] sticks = new Chopstick[size];
for(int i = 0; i < size; i++)
sticks[i] = new Chopstick();
for(int i = 0; i < size; i++)
es.execute(new Philosopher(
sticks[i], sticks[(i+1) % size], i, ponder));
if(args.length == 3 && args[2].equals("timeout"))
new Nap(5000);
else {
System.out.println("Press 'Enter' to quit");
try {
System.in.read();
} catch(Exception e) {
throw new RuntimeException(e);
}
}
es.shutdownNow();
}
}
/* Output: (First and Last 10 Lines)
Philosopher 0 thinking
Philosopher 4 thinking
Philosopher 1 thinking
Philosopher 3 thinking
Philosopher 2 thinking
Philosopher 3 grabbing right
Philosopher 1 grabbing right
Philosopher 4 grabbing right
Philosopher 0 grabbing right
Philosopher 4 grabbing left
...________...________...________...________...
Philosopher 3 grabbing left
Philosopher 1 grabbing left
Philosopher 4 grabbing left
Philosopher 2 grabbing left
Philosopher 0 grabbing left
Philosopher 1 exiting via interrupt
Philosopher 4 exiting via interrupt
Philosopher 3 exiting via interrupt
Philosopher 2 exiting via interrupt
Philosopher 0 exiting via interrupt
*/

View File

@ -0,0 +1,64 @@
// concurrent/DiningPhilosophers.java
// (c)2016 MindView LLC: see Copyright.txt
// We make no guarantees that this code is fit for any purpose.
// Visit http://OnJava8.com for more book information.
// Deadlock can be hidden in a program
import java.util.stream.*;
import java.util.concurrent.*;
import static java.util.concurrent.TimeUnit.*;
public class DiningPhilosophers {
static void stopAfter(int secs) {
ScheduledExecutorService sched =
Executors.newScheduledThreadPool(1);
sched.schedule( () -> {
System.out.println("Timeout");
Philosopher.running.set(false);
sched.shutdownNow();
System.exit(0);
}, secs, SECONDS);
}
public static void main(String[] args)
throws Exception {
stopAfter(3);
try {
IntStream.range(0, Philosopher.QUANTITY)
.mapToObj(Philosopher::new)
.map(CompletableFuture::runAsync)
.collect(Collectors.toList())
.forEach(CompletableFuture::join);
} catch(CompletionException ex) {
Philosopher.running.set(false);
System.out.println("Broken out of deadlock");
System.out.println("...");
}
Philosopher.trace.stream()
.skip(Philosopher.trace.size() - 20)
.forEach(System.out::println);
}
}
/* Output:
Broken out of deadlock
...
P2 grabbing right
P1 grabbing left
P3 eating
P3 thinking
P3 grabbing right
P4 eating
P2 grabbing left
P4 thinking
P0 eating
P4 grabbing right
P3 grabbing left
P0 thinking
P0 grabbing right
P4 grabbing left
P0 grabbing left
P1 eating
P2 eating
P3 eating
P0 eating
P4 eating
Timeout
*/

View File

@ -5,42 +5,108 @@
import java.util.concurrent.*;
public class DualCompletableOperations {
static
CompletableFuture<RandomWork> makeCF(int id) {
return
CompletableFuture.completedFuture(
new RandomWork(id))
.thenApplyAsync(RandomWork::work);
}
static CompletableFuture<RandomWork> cfA, cfB;
static int count = 0;
static CompletableFuture<Workable> cfA, cfB;
static void init() {
cfA = makeCF(count++);
cfB = makeCF(count++);
cfA = Workable.make("A", 150);
cfB = Workable.make("B", 100); // Always wins
}
static void join() {
cfA.join();
cfB.join();
System.out.println("*****************");
}
public static void main(String[] args) {
init();
cfA.runAfterBothAsync(cfB, () ->
System.out.println("Completed Both"));
join();
init();
cfA.runAfterEitherAsync(cfB, () ->
System.out.println("Completed Either"));
System.out.println("runAfterEither"));
join();
init();
cfA.applyToEitherAsync(cfB, rw -> {
System.out.println("applyToEither: " + rw);
return rw;
cfA.runAfterBothAsync(cfB, () ->
System.out.println("runAfterBoth"));
join();
init();
cfA.applyToEitherAsync(cfB, w -> {
System.out.println("applyToEither: " + w);
return w;
});
join();
init();
cfA.acceptEitherAsync(cfB, w -> {
System.out.println("acceptEither: " + w);
});
join();
init();
cfA.thenAcceptBothAsync(cfB, (w1, w2) -> {
System.out.println("thenAcceptBoth: "
+ w1 + ", " + w2);
});
join();
init();
cfA.thenCombineAsync(cfB, (w1, w2) -> {
System.out.println("thenCombine: "
+ w1 + ", " + w2);
return w1;
});
join();
init();
CompletableFuture<Workable>
cfC = Workable.make("C", 75),
cfD = Workable.make("D", 99);
CompletableFuture.anyOf(cfA, cfB, cfC, cfD)
.thenRunAsync(() ->
System.out.println("anyOf"));
join();
init();
cfC = Workable.make("C", 75);
cfD = Workable.make("D", 99);
CompletableFuture.allOf(cfA, cfB, cfC, cfD)
.thenRunAsync(() ->
System.out.println("allOf"));
join();
}
}
/* Output:
Workable[BW]
runAfterEither
Workable[AW]
*****************
Workable[BW]
Workable[AW]
*****************
runAfterBoth
Workable[BW]
applyToEither: Workable[BW]
Workable[AW]
*****************
Workable[BW]
acceptEither: Workable[BW]
Workable[AW]
*****************
Workable[BW]
Workable[AW]
*****************
thenAcceptBoth: Workable[AW], Workable[BW]
Workable[BW]
Workable[AW]
*****************
thenCombine: Workable[AW], Workable[BW]
Workable[CW]
anyOf
Workable[DW]
Workable[BW]
Workable[AW]
*****************
Workable[CW]
Workable[DW]
Workable[BW]
Workable[AW]
*****************
allOf
*/

View File

@ -1,65 +0,0 @@
// concurrent/FixedDiningPhilosophers.java
// (c)2016 MindView LLC: see Copyright.txt
// We make no guarantees that this code is fit for any purpose.
// Visit http://OnJava8.com for more book information.
// Dining philosophers without deadlock
// {java FixedDiningPhilosophers 5 5 timeout}
import java.util.concurrent.*;
import onjava.Nap;
public class FixedDiningPhilosophers {
public static void
main(String[] args) {
int ponder = 5;
if(args.length > 0)
ponder = Integer.parseInt(args[0]);
int size = 5;
if(args.length > 1)
size = Integer.parseInt(args[1]);
ExecutorService es = Executors.newCachedThreadPool();
Chopstick[] sticks = new Chopstick[size];
for(int i = 0; i < size; i++)
sticks[i] = new Chopstick();
for(int i = 0; i < size; i++)
if(i < (size-1))
es.execute(new Philosopher(
sticks[i], sticks[i+1], i, ponder));
else
es.execute(new Philosopher(
sticks[0], sticks[i], i, ponder));
if(args.length == 3 && args[2].equals("timeout"))
new Nap(5000);
else {
System.out.println("Press 'Enter' to quit");
try {
System.in.read();
} catch(Exception e) {
throw new RuntimeException(e);
}
}
es.shutdownNow();
}
}
/* Output: (First and Last 10 Lines)
Philosopher 1 thinking
Philosopher 4 thinking
Philosopher 2 thinking
Philosopher 0 thinking
Philosopher 3 thinking
Philosopher 1 grabbing right
Philosopher 2 grabbing right
Philosopher 4 grabbing right
Philosopher 4 grabbing left
Philosopher 4 eating
...________...________...________...________...
Philosopher 1 thinking
Philosopher 0 grabbing left
Philosopher 0 eating
Philosopher 2 eating
Philosopher 1 grabbing right
Philosopher 3 exiting via interrupt
Philosopher 1 exiting via interrupt
Philosopher 2 exiting via interrupt
Philosopher 0 exiting via interrupt
Philosopher 4 exiting via interrupt
*/

View File

@ -0,0 +1,31 @@
// concurrent/FrostedCake.java
// (c)2016 MindView LLC: see Copyright.txt
// We make no guarantees that this code is fit for any purpose.
// Visit http://OnJava8.com for more book information.
import java.util.concurrent.*;
import java.util.function.*;
import java.util.stream.*;
import onjava.Nap;
class Frosting {
private Frosting() {}
static CompletableFuture<Frosting> make() {
new Nap(100);
return CompletableFuture
.completedFuture(new Frosting());
}
}
public class FrostedCake {
public FrostedCake(Baked baked, Frosting frosting) {
new Nap(100);
}
public static void main(String[] args) {
Baked.batch().forEach(baked -> baked
.thenCombineAsync(Frosting.make(),
(cake, frosting) ->
new FrostedCake(cake, frosting))
.thenAcceptAsync(System.out::println).join());
// Need to rewrite...
}
}

View File

@ -31,3 +31,7 @@ public class ParallelPrime {
StandardOpenOption.CREATE);
}
}
/* Output:
/* Output:
616
*/

View File

@ -23,3 +23,6 @@ public class ParallelStreamPuzzle {
System.out.println(x);
}
}
/* Output:
[2, 8, 21, 24, 27, 30, 33, 37, 40, 43]
*/

View File

@ -2,48 +2,58 @@
// (c)2016 MindView LLC: see Copyright.txt
// We make no guarantees that this code is fit for any purpose.
// Visit http://OnJava8.com for more book information.
// A dining philosopher
import java.util.*;
import onjava.Nap;
import java.util.stream.*;
import java.util.concurrent.*;
import static java.util.concurrent.TimeUnit.*;
import java.util.concurrent.atomic.*;
public class Philosopher implements Runnable {
private Chopstick left;
private Chopstick right;
private final int id;
private final int ponderFactor;
private SplittableRandom rand = new SplittableRandom(47);
private void pause() {
if(ponderFactor == 0) return;
new Nap(rand.nextInt(ponderFactor * 250));
}
public Philosopher(Chopstick left, Chopstick right,
int ident, int ponder) {
this.left = left;
this.right = right;
id = ident;
ponderFactor = ponder;
class Philosopher implements Runnable {
static class Chopstick {}
public static final int QUANTITY = 5;
static Queue<String> trace =
new ConcurrentLinkedQueue<>();
static AtomicBoolean running =
new AtomicBoolean(true);
public static
List<BlockingQueue<Chopstick>> chopsticks =
IntStream.range(0, Philosopher.QUANTITY)
.mapToObj(i -> {
BlockingQueue<Chopstick> bd =
new ArrayBlockingQueue<>(1);
bd.add(new Chopstick());
return bd;
})
.collect(Collectors.toList());
private final int seatNumber;
private final int left, right;
public Philosopher(int seatNumber) {
this.seatNumber = left = seatNumber;
right = (seatNumber + 1) % QUANTITY;
}
@Override
public void run() {
try {
while(!Thread.interrupted()) {
System.out.println(this + " " + "thinking");
pause();
while(running.get()) {
trace.add(this + " thinking");
// Philosopher becomes hungry
System.out.println(this + " " + "grabbing right");
right.take();
System.out.println(this + " " + "grabbing left");
left.take();
System.out.println(this + " " + "eating");
pause();
right.drop();
left.drop();
trace.add(this + " grabbing right");
Chopstick rightStick =
chopsticks.get(right).poll(2, SECONDS);
trace.add(this + " grabbing left");
Chopstick leftStick =
chopsticks.get(left).poll(2, SECONDS);
trace.add(this + " eating");
// Finished, return chopsticks to table:
chopsticks.get(right).put(rightStick);
chopsticks.get(left).put(leftStick);
}
} catch(InterruptedException e) {
System.out.println(
this + " " + "exiting via interrupt");
trace.add("exiting via interrupt");
}
}
@Override
public String toString() { return "Philosopher " + id; }
public String toString() {
return "P" + seatNumber;
}
}

View File

@ -22,3 +22,14 @@ public class QuittingTasks {
es.shutdown();
}
}
/* Output:
125 148 115 127 120 118 106 140 77 119 97 80 143 17 92 147
89 123 16 12 138 25 13 101 135 96 76 73 130 133 37 132 134
149 137 122 29 49 60 40 142 131 53 1 98 145 126 65 5 64 82
79 68 86 141 61 128 22 7 26 19 139 114 146 14 15 43 34 10
75 87 90 31 47 38 62 18 63 41 42 144 66 23 6 4 91 70 83 102
103 54 69 74 56 71 94 88 78 81 57 52 93 45 48 44 32 28 36
33 104 105 112 109 100 117 24 108 21 116 20 9 85 8 84 72
107 113 121 124 136 129 99 95 55 3 27 2 59 67 50 58 51 39
30 35 46 110 111 11
*/

View File

@ -1,22 +0,0 @@
// concurrent/RandomWork.java
// (c)2016 MindView LLC: see Copyright.txt
// We make no guarantees that this code is fit for any purpose.
// Visit http://OnJava8.com for more book information.
import java.util.*;
import onjava.Nap;
public class RandomWork {
private static SplittableRandom rand =
new SplittableRandom(47);
private final int id;
public RandomWork(int id) { this.id = id; }
public static RandomWork work(RandomWork r) {
new Nap(rand.nextInt(250));
System.out.println(r);
return r;
}
@Override
public String toString() {
return "RandomWork " + id;
}
}

View File

@ -36,8 +36,8 @@ public class Summing2 {
}
/* Output:
200000010000000
Array Stream Sum: 112ms
Parallel: 28ms
Basic Sum: 33ms
parallelPrefix: 60ms
Array Stream Sum: 22ms
Parallel: 21ms
Basic Sum: 16ms
parallelPrefix: 116ms
*/

32
concurrent/Workable.java Normal file
View File

@ -0,0 +1,32 @@
// concurrent/Workable.java
// (c)2016 MindView LLC: see Copyright.txt
// We make no guarantees that this code is fit for any purpose.
// Visit http://OnJava8.com for more book information.
import java.util.concurrent.*;
import onjava.Nap;
public class Workable {
String id;
final int duration;
public Workable(String id, int duration) {
this.id = id;
this.duration = duration;
}
@Override
public String toString() {
return "Workable[" + id + "]";
}
public static Workable work(Workable tt) {
new Nap(tt.duration); // Milliseconds
tt.id = tt.id + "W";
System.out.println(tt);
return tt;
}
public static CompletableFuture<Workable>
make(String id, int duration) {
return
CompletableFuture.completedFuture(
new Workable(id, duration))
.thenApplyAsync(Workable::work);
}
}

View File

@ -14,7 +14,7 @@ project(':understandingcollections') {
}
}
project(':concurrent') {
project(':lowlevel') {
dependencies {
compile project(':enums')
}

View File

@ -1,4 +1,4 @@
// concurrent/BankTellerSimulation.java
// lowlevel/BankTellerSimulation.java
// (c)2016 MindView LLC: see Copyright.txt
// We make no guarantees that this code is fit for any purpose.
// Visit http://OnJava8.com for more book information.

View File

@ -1,4 +1,4 @@
// concurrent/CarBuilder.java
// lowlevel/CarBuilder.java
// (c)2016 MindView LLC: see Copyright.txt
// We make no guarantees that this code is fit for any purpose.
// Visit http://OnJava8.com for more book information.

View File

@ -1,4 +1,4 @@
// concurrent/Restaurant.java
// lowlevel/Restaurant.java
// (c)2016 MindView LLC: see Copyright.txt
// We make no guarantees that this code is fit for any purpose.
// Visit http://OnJava8.com for more book information.

View File

@ -1,4 +1,4 @@
// concurrent/ToastOMatic.java
// lowlevel/ToastOMatic.java
// (c)2016 MindView LLC: see Copyright.txt
// We make no guarantees that this code is fit for any purpose.
// Visit http://OnJava8.com for more book information.

View File

@ -1,4 +1,4 @@
// concurrent/restaurant2/RestaurantWithQueues.java
// lowlevel/restaurant2/RestaurantWithQueues.java
// (c)2016 MindView LLC: see Copyright.txt
// We make no guarantees that this code is fit for any purpose.
// Visit http://OnJava8.com for more book information.