Moved examples from "Concurrent" to "lowlevel"
This commit is contained in:
parent
c590aeb851
commit
afa51c5b7a
31
concurrent/Baked.java
Normal file
31
concurrent/Baked.java
Normal 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
34
concurrent/Batter.java
Normal 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
26
concurrent/Breakable.java
Normal 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;
|
||||
}
|
||||
}
|
79
concurrent/CatchCompletableExceptions.java
Normal file
79
concurrent/CatchCompletableExceptions.java
Normal 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]
|
||||
*/
|
@ -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();
|
||||
}
|
||||
}
|
@ -19,3 +19,9 @@ public class CompletableApply {
|
||||
cf4.thenApply(Machina::work);
|
||||
}
|
||||
}
|
||||
/* Output:
|
||||
Machina0: ONE
|
||||
Machina0: TWO
|
||||
Machina0: THREE
|
||||
Machina0: complete
|
||||
*/
|
||||
|
69
concurrent/CompletableExceptions.java
Normal file
69
concurrent/CompletableExceptions.java
Normal 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
|
||||
*/
|
@ -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
|
||||
*/
|
||||
|
@ -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
|
||||
*/
|
||||
|
@ -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
|
||||
*/
|
64
concurrent/DiningPhilosophers.java
Normal file
64
concurrent/DiningPhilosophers.java
Normal 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
|
||||
*/
|
@ -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
|
||||
*/
|
||||
|
@ -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
|
||||
*/
|
31
concurrent/FrostedCake.java
Normal file
31
concurrent/FrostedCake.java
Normal 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...
|
||||
}
|
||||
}
|
@ -31,3 +31,7 @@ public class ParallelPrime {
|
||||
StandardOpenOption.CREATE);
|
||||
}
|
||||
}
|
||||
/* Output:
|
||||
/* Output:
|
||||
616
|
||||
*/
|
||||
|
@ -23,3 +23,6 @@ public class ParallelStreamPuzzle {
|
||||
System.out.println(x);
|
||||
}
|
||||
}
|
||||
/* Output:
|
||||
[2, 8, 21, 24, 27, 30, 33, 37, 40, 43]
|
||||
*/
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
*/
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
@ -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
32
concurrent/Workable.java
Normal 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);
|
||||
}
|
||||
}
|
@ -14,7 +14,7 @@ project(':understandingcollections') {
|
||||
}
|
||||
}
|
||||
|
||||
project(':concurrent') {
|
||||
project(':lowlevel') {
|
||||
dependencies {
|
||||
compile project(':enums')
|
||||
}
|
||||
|
@ -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.
|
@ -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.
|
@ -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.
|
@ -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.
|
@ -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.
|
Loading…
x
Reference in New Issue
Block a user