Concurrent Programming in Java

Ruben Inoto Soto
Ruben Inoto SotoSenior Software Architect at Red Bull Media House
Concurrent Programming in Java
Index
● Concurrency
● Threads
● Executors
● ForkJoin
● Paralell Streams
● CompletableFuture
● RXJava
● Actors
Concurrency?
„a property of systems in which
several computations are
executing simultaneously, and
potentially interacting with each
other“
http://en.wikipedia.org/wiki/Concurrency_(computer_science)
Why Concurrency?
Concurrency vs Paralellism
Paralell
Concurrent
context
switching
Amdahl's Law
The speedup of a program
using multiple processors
in parallel computing is
limited by the sequential
fraction of the program.
For example, if 95% of the program can be parallelized, the theoretical maximum speedup using parallel
computing would be 20× as shown in the diagram, no matter how many processors are used.
Concurrency
Paralellism
no
context
switch
context
switch
http://www.scanvine.com/source/daily-beasthttp://20minutosderisa.blogspot.co.at/
Java1.0 - Threads
public class TestRunnable implements Runnable {
public void run() {
//do something
}
}
Thread t = new Thread(new TestRunnable());
t.start(); //Thread starts
t.join(1000); //Waits 1 second until thread finishes
t.isAlive(); //checks if thread is alive
t.interrupt(); // stops thread
Communication betwen Threads
● Threads communicate by sharing access to
fields
● This kind of communication can lead to:
– Thread interference: sequence of steps overlap,
leading to wrong results.
– Memory consistency errors: changes to objects
are not immediatelly visible to other threads
Thread Interference
– sequence of
steps overlap,
leading to
wrong results
Memory Consistency Errors
//thread A increments counter
counter++;
// counter is shared by 2
threads
int counter = 0;
Thread A Thread B
//thread B prints out counter,
// right after A's change
System.out.println(counter);
Which value prints out B?
there's no guarantee that thread A's change to counter will be visible to thread B,
unless the programmer has established a happens-before relationship between these two statements
Threads
● To prevent Thread Interference and Memory
Consistency errors, we use synchronization,
that can introduce Thread Contention
– Deadlocks: threads wait for each other forever.
– Starvation: thread blocks for a long time, because
synchronized block takes too much time to execute.
– Livelocks: threads introduce logic to avoid
deadlocks, but they fail reapeatedly.
Deadlock
Thread Problems
● Expensive to create
– CPU + RAM (around. 512Kb per Thread!)
● Performance overhead when CPU does context switching (switching
between threads)
– Everytime a thread blocks or sleeps, context is switched
● Memory is shared around threads
– Problem with concurrent access to shared objects
● Difficult to control flow
● Difficult to control the number of threads started
● Locks to control access to shared resources
– Can introduce thread contention
Java5 – Concurrency
Enhancements
● Atomic Numbers (AtomicInteger): get and
increment a value atomically
● Concurrent Collections (e.g.
ConcurrentHashMap): supports concurrent
reads and updates
● ExecutorService
● Futures
ExecutorService
●
Takes care of executing (and controlling the execution) of asynchronous
tasks
●
Configurable Thread Pools
– CorePoolSize
– MaximumPoolSize,
– KeepAliveTime
– ThreadFactory
– RejectedExecutionHandler
● Predefined Executors
– Cached
– Fixed
– Scheduled
– SingleThreaded
http://blog.jessitron.com/2014/01/choosing-executorservice.html
Executor
Executor executor = new ThreadPoolExecutor(...)
executor.execute(new Runnable() {
public void run() {
//execute task
}
});
● Parent Interface of ExecutorService
● Just provides one method: execute
ExecutorService
//creates the executor service
ExecutorService executorService = Executors.newFixedThreadPool(5);
//submits a task to be executed asynchronously
Future<String> future = executorService.submit(new Callable<String>() {
@Override
public String call() throws Exception {
return "hi";
}
});
//blocks until the result is ready
String message = future.get();
// no more executions will be accepted
executorService.shutdown();
// blocks until all tasks have completed execution
executorService.awaitTermination(1, TimeUnit.SECONDS);
ExecutorService + Callable + Future
//submits a task to be executed asynchronously
Future<String> future = executorService.submit(new Callable<String>() {
@Override
public String call() throws Exception {
return "hi";
}
});
//blocks until the result is ready
String message = future.get();
Blocks until result is ready (thread has finished)
● Callable allows threads to return a result
● Future holds the result of the asynchronous computation
Future methods
● get()
– BLOCKS until result is ready
● get(timeout) throws TimeoutException
● cancel(mayInterruptIfRunning)
– If task has not started, it will not be started
– Otherwise, if mayInterruptIfRunning is true, it will Interrupt
● isDone()
● isCancelled()
ExecutorService – more methods
● List<Future> invokeAll(Collection <Callable> Tasks
– Executes all tasks, and returns when ALL have completed
execution
● Object invokeAny(Collection<Callable>)
– Starts execution of all tasks and returns the result of one finished
task. Tasks that have not completed, are cancelled.
● invoke* and await* methods support timeout parameters. If
task doesn't finish on time, method still returns
ExecutorService - Pros
● Now we can:
– Cache Threads => less overhead
– Control Size of Pool => less risk of OOM
– Easily retrieve values of asynchronous computation
(Future)
– Submit multiple tasks simultaneously
Executors - Cons
● How to control multiple executions?
Future<String> fA = executorService.submit(....);
Future<String> fB = executorService.submit(....);
Future<String> fC = executorService.submit(....);
String a = fA.get();
String b = fB.get();
String c = fC.get();
What if fB and fC are ready before fA?
Executors - Cons
● How to nest calls?
Future<String> fA = executorService.submit(new RemoteCall());
Future<String> fB = executorService.submit(new RemoveCallWithParam(fA.get());
…..........
String a = fA.get();
String a = fB.get();
fA.get()
BLOCKS!
Callbacks
executorService.execute(new RemoteCall(new Callback() {
public void notify(Object param) {
//remote call has finished – do something
}
}));
//continue doing something
interface Callback {
void notify(Object param);
}
class RemoteCall implements Runnable {
private Callback callback;
public RemoteCall(Callback callback) {
this.callback = callback;
}
public void run() {
//execute remote call
callback.notify(param)
}
}
when RemoteCall finishes
it notifies the registered callback
no
blocking
Executors - Cons
● Futures block and are difficult to nest
● Callbacks do not block, but do not solve the
problem of nested composition
Java7 - ForkJoin
● Implementation of ExecutorService
● Aims to utilize a multi-core architecture at a
maximum
● Uses a work-stealing algorithm: if a worker
runs out of tasks, can steal work from others
● Useful for recursive tasks
if (my portion of the work is small enough)
do the work directly
else
split my work into two pieces
invoke the two pieces and wait for the results
No Work-Stealing
http://dantravelling.wordpress.com/2012/03/02/short-haul-in-europe-sk547-cph-ams/
public class ForkSum extends RecursiveAction {
private final int[] array;
private final int start;
private final int end;
private final AtomicInteger result;
public ForkSum(int[] array, int start, int end, AtomicInteger result) {
super();
this.array = array;
this.start = start;
this.end = end;
this.result = result;
}
private void computeDirectly() {
int partialSum = 0;
for (int i = start; i < end; i++) {
partialSum += array[i];
}
result.addAndGet(partialSum);
}
@Override
protected void compute() {
if ((start - end) < 10) {
computeDirectly();
} else {
int delta = (end - start) / 2;
ForkSum a = new ForkSum(array, start, start + delta, result);
ForkSum b = new ForkSum(array, start + delta + 1, end, result);
invokeAll(a, b);
}
}
int[] array = new int[2046];
Arrays.fill(array, 2);
AtomicInteger result = new AtomicInteger(0);
ForkSum forkSum = new ForkSum(array, 0, array.length, result);
ForkJoinPool pool = new ForkJoinPool();
pool.invoke(forkSum);
System.out.println(forkSum.getResult());
ForkJoinPool uses work stealing
We can set the „parallelism level“ to ForkJoinPool
(defaults to number of processors)
Java7 - ForkJoin
● Only really useful for recursive tasks
● Does not help with the problems with had in the
Executors (blocking & nested composition)
Java8 – Streams
// PROBLEM: Perform a time-intensive computation
// to each element of the list
List<Integer> col = Arrays.asList(1, 2, 3);
// Procedural Solution
List<Integer> colResult = new ArrayList<Integer>();
for (Integer i : col) {
colResult.add(expensiveOperation(i));
}
//Functional Solution: use map() with a HighOrderFunction
List<Integer> colResultF =
col.stream().map(i -> expensiveOperation(i))
.collect(Collectors.toList());
Java8 – Parallel Streams
//Functional Solution+:
// parallelize the stream
// and use map() with a HighOrderFunction
List<Integer> colResultFP =
col.parallelStream().map(i -> expensiveOperation(i))
.collect(Collectors.toList());
Java8 - CompletableFuture
● Futures with
– Callbacks
– Transformations
– Possibility to explicitly set a value in the Future (i.e.
Promise)
Completing a CompletableFuture
//CALLEE
public CompletableFuture<String> doSomething() {
final CompletableFuture<String> future = createFuture();
// do something (synch or asynch)
// when ready, call
future.complete("hi");
// that will unlock the clients waiting for the future
return future;
}
//CALLER
CompletableFuture<String> cf = doSomething();
// Blocks until callee „completes“ the future with f.complete
String result = cf.get();
will normally be executed asynch
blocks
How to get a value from a
CompletableFuture
● get()
– BLOCKS until the value is present, and returns it
● get(timeout, timeoutUnit)
– BLOCKS until the value is present, or the timeout has been
reached. If the later , a TimeoutException is thrown
● getNow(valueIfAbsent)
– Doesn't block! if the value is present, it returns it; otherwise,
the valueIfAbsent param (default) is returned
How to complete a
CompletableFuture
● complete(value)
– completes ok with the value
– only the first call takes effect – subsequent calls are
ignored
● completeExceptionally(ex)
– completes with exception
– get() will throw an exception in the caller
● cancel()
– completes with a CancellationException
Completing a CompletableFuture
● Why is this useful?
– We can execute a task sometimes in synchronous,
and sometimes in asynchronous mode, without
having to change the client. We just deliver a
CompletableFuture, and the implementation
decides the execution mode.
Creating a CompletableFuture
// <Java7
CompletableFuture<String> f = CompletableFuture.supplyAsync( new Supplier<String>() {
@Override
public String get() {
// perform task
return "hi";
}
}, executorService);
// OR Using Lambdas
CompletableFuture<String> ft = CompletableFuture.supplyAsync(
() -> "hi", executorService);
Supplier is a
functional
interface
Similar to
Callable
if no executor is provided,
the ForkJoinPool.commonPool will be used
Creating a CompletableFuture
● CompletableFuture<T>
CompletableFuture.supplyAsync(supplier<T>,
executor>
– If no executor is provided, a Common Static pool for all
tasks called ForkJoinPool.commonPool wil be used. This
executor cannot be shutdown
● CompletableFuture<Void>
CompletableFuture.runAsync(runnable, exec)
– Accepts a Runnable instead of a Supplier → no value will
be returned
CompletableFuture
Registering Callbacks
● .thenApply → registers a callback, that will be
executed asynchronously when the future is
ready. It uses the same thread that executed
the future!
● .thenApplyAsynch → same as .thenApply, but
the callback will be executed in a different
thread than the one that completed the future
map in fp terms
CompletableFuture - Nesting and
Composing
CompletableFuture<Order> f1 = persistOrder(o);
CompletableFuture<Order> f2 = f1.thenApply(o → transferOrderToContractor(o));
CompletableFuture<Order> f3 = f2.thenApply(o → updateSearchIndex(o));
CompletableFuture<Order> f4 = f3.thenApply(o → sendMonitoringInfo(o));
//OR, in a line:
CompletableFuture<Order> f1 = persistOrder(o)
.thenApply(o → transferOrderToContractor(o))
.thenApply(o → updateSearchIndex(o))
.thenApply(o → sendMonitoringInfo(o));
thenApply
doesn't block!
operations
are executed
in order, but
do not block
map in fp terms
Set<Order> ordersToProcess = ….;
ordersToProcess.stream().map(o → persistOrder(o)
.thenApply(o → transferOrderToContractor(o))
.thenApply(o → updateSearchIndex(o))
.thenApply(o → sendMonitoringInfo(o)));
CompletableFuture
Multiple Items
CompletableFuture<Order> f1 = persistOrder(o);
CompletableFuture<Order> f2 = f1.thenApply(o → transferOrderToContractor(o));
f2.thenAccept(o → logger.debug(„Order „ + o + „ succesfully processed“);
CompletableFuture
Consuming Final Value
● thenAccept → accepts a function that will be
executed when the CompletableFuture has
finished
CompletableFuture
Error Handling
● exceptionally → accepts a function with the
exception as parameter
● handle → accepts a function with both the
normal result AND the exception as parameter,
but only one of them is set
CompletableFuture<Order> f1 = persistOrderAsynch(o);
f1.exceptionally(e -> sendAlertMessage(e));
//OR
f1.handle((order, ex) -> {
if (ex != null) {
sendAlertMessage(ex);
return null;
} else {
logger.info("Order persisted: " + order);
return order;
}
});
CompletableFuture
Composing
● CompletableFutures provides functions to
combine multiple futures together
● thenCompose → same as thenApply, but the
function that accepts returns a
CompletableFuture
private CompletableFuture<Status> sendData(String data) {…};
CompletableFuture<String> f1 = retrieveData();
CompletableFuture<Status> fs = f1.thenCompose(data → sendData(data));
flatMap in fp terms
CompletableFuture
Combining
● thenCombine → executes a callback when 2
completableFutures finish
CompletableFuture<Address> f1 = retrieveContactAddress(contact);
CompletableFuture<Identification> f2 = retrieveContactIdentification(contact);
CompletableFuture<String> fs = f1.thenCombine(f2,
(address, id) → peristContactData(address id));
CompletableFuture
Accepting one
● acceptEither → returns the future that
completes first
● applyToEither → same than accept either, but
it executes a callback when the first future
completes
CompletableFuture<Contact> f1 = searchContactInDB(name);
CompletableFuture<Contact> f2 = searchContactInIndex(name);
CompletableFuture<Contact> fs = f1.applyToEither(f2,
c → sysout(„Contact found: „ + c);
we do not care who
finishes first.
Just want one
CompletableFuture
Static Methods
● anyOf → static method, similar to acceptEither,
that returns the future that completes first
● allOf → static method, that returns a future that
will complete when all futures complete
CompletableFuture<Contact> f1 = searchContactInDB(name);
CompletableFuture<Contact> f2 = searchContactInIndex(name);
CompletableFuture<Contact> fs = CompletableFuture.anyOf(f1, f2);
we do not care who
finishes first.
Just want one
CompletablFuture - Problems
● Transactions
– In a EE App Server, we can use the
ManagedExecutorService
– Tasks submitted via ManagedExecutorService can
get components @Injected (e.g. EntitiyManager)
@Resource
ManagedExecutorService managedExecutorService;
RX Java
● Java Implementation of ReactiveExtensions (.NET)
● Library for composing asynchronous and event-based
programs
● Introduces the Observable type (extension the Observer GOF
Pattern)
– consumer subscribes to an event, and producer pushes data when
available
● Can be seen as an Iterator that, instead of pulling, gets the data
pushed.
● Futures work on single items – Observables work on multiple
items
event Iterable (pull) Observable (push)
retrieve data T next() onNext(T)
discover error throws Exception onError(Exception)
complete returns onCompleted()
Iterable vs Observable
An Observable is the asynchronous/push "dual" to the
synchronous/pull Iterable
4 3 2 1….
PULL
PUSH
4 3 2 1….
Observable<String> homeMadeSyncObservable = Observable.create(new OnSubscribe<String>() {
@Override
public void call(Subscriber<? super String> subscriber) {
subscriber.onNext("1");
subscriber.onNext("2");
subscriber.onNext("3");
subscriber.onCompleted();
}
});
Creating Observables - Sync
Observable<String> observable = Observable.from(Arrays.asList("1", "2", "3"));
● Observable.create
• Observable.from
Observable.from(numbers).subscribe(n -> System.out.println("value received: " + n),
t -> System.out.println("Exception thrown: " + t),
() -> System.out.println("observable completed")
);
Subscribing to Observables
● subscribe function accepts three parameters in the form
of functions
– onNext → function to be called when a value is emitted. The
value is passed as parameter to the function.
– onError → function to be called when an exception is emitted.
The exception is passed as parameter to the function
– onComplete → function to be called when the observable
doesn't have any more value to emit (has finished). This function
doesn't accept any parameter.
Holly Lambdas!
Observable.from(numbers).subscribe(new Action1<Integer>() {
@Override
public void call(Integer n) {
System.out.println("value received: " + n);
}
}, new Action1<Throwable>() {
@Override
public void call(Throwable t) {
System.out.println("Exception thrown: " + t);
}
}, new Action0() {
@Override
public void call() {
System.out.println("observable completed");
}
});
Observable.from(numbers).subscribe(n -> System.out.println("value received: " + n),
t -> System.out.println("Exception thrown: " + t),
() -> System.out.println("observable completed")
);Java8
Java7
Subscribing to Observables
● Instead of passing three functions to subscribe,
we can implement the Observer Interface.
public interface Observer<T> {
/**
* Notifies the Observer that the {@link Observable} has finished sending push-based
notifications.
public abstract void onCompleted();
/**
* Notifies the Observer that the {@link Observable} has experienced an error condition.
*/
public abstract void onError(Throwable e);
/**
* Provides the Observer with new data.
*/
public abstract void onNext(T t);
}
Subscribing to Observables
● or, if we are just interested in the values, we
can just „listen“ to the emitted values by
passing just the first function
Observable<Integer> observable = Observable.from(1, 2, 3);
observable.subscribe(t -> System.out.println(t));
4 3 2 1….
OBSERVABLE
OBSERVER
Observable.from(Arrays.asList("1", "2", "3"));
obs.subscribe
(n -> echo("value received: " + n),
t -> echo("Exception thrown: " + t),
() -> echo("observable completed")
);
Subscriptions
● Observable.subscribe() returns a
Subscription object, that offers two methods:
/**
* Stop receiving notifications on the {@link Subscriber}
that was registered when this Subscription was received.
* <p>
* This allows unregistering an {@link Subscriber} before it
has finished receiving all events (ie. before onCompleted is called).
*/
public void unsubscribe();
public boolean isUnsubscribed();
● If we unsubscribe, the Observer will stop
receiving events
Observable<String> homeMadeAsyncObservable = Observable.create(new OnSubscribe<String>() {
@Override
public void call(Subscriber<? super String> subscriber) {
final Thread thread = new Thread(() -> {
subscriber.onNext("1");
subscriber.onNext("2");
subscriber.onNext("3");
subscriber.onCompleted();
});
thread.start();
}
});
Creating Observables - Async
● Observable.create – Async with Thread
final ExecutorService threadPool = Executors.newCachedThreadPool();
Observable<String> observableWithExecutor = Observable.create(new OnSubscribe<String>() {
@Override
public void call(Subscriber<? super String> subscriber) {
threadPool.execute(() -> subscriber.onNext("a"));
threadPool.execute(() -> subscriber.onNext("b"));
threadPool.execute(() -> subscriber.onNext("c"));
try {
threadPool.shutdown();
threadPool.awaitTermination(2, TimeUnit.SECONDS);
subscriber.onCompleted();
} catch (InterruptedException e) {
subscriber.onError(e);
}
}
});
Creating Observables - Async
● Observable.create – Async with Executors
Transforming Observables
● map() and flatMap() → same as thenApply and
thenCompose in CompletableFuture
observable.map( n -> n + 1)
→ Observable(2, 3, 4)
observable.flatMap( n -> Observable.from(n+1))
→ Observable(2, 3, 4)
● groupBy, scan, pivot, buffer, window...
Observable<Integer> observable = Observable.from(1, 2, 3);
Filtering Observables
List<String> names = Arrays.asList("Stefan",
"Sebastian", "Ruben", "Robert", "Harald");
Observable.from(names).filter(s ->
s.startsWith("S"));
→ Observable(„Stefan“, „Sebastian“)
Observable.from(names).take(2));
→ Observable(„Stefan“, „Sebastian“)
takeLast, first, elementAt, sample, timeout, distinct, ofType, ...
Combining Observables
zip, join, paralellMerge, combineLatest...
MUCH more on RXJava
https://github.com/Netflix/RxJava/wiki/
Functional Reactive Programming
(Netflix)
● All return types are Observable. The service
layer decides to:
– return immediately with a value (i.e. value in cache)
– or block until result available
– or return immediately and perform execution
asynchronously
Actors
● originated in 1973
● objects that encapsulate state and behaviour
● very lightweight concurrent entities
● process messages asynchronously using an
event-driven receive loop
● they communicate only via messages
● raise the abstraction level to work with events
flowing through the system
Actors
MESSAGE
SENDER
MAILBOX
ACTOR
BEHAVIOUR
DISPATCHER
Actors - Supervising
Actors build „trees
of Actors“, forming
a hierarchical
structure
each actor has exactly one
supervisor, which is the actor that
created it
tasks are split up
and delegated until
they become small
enough to be handled
in one piece
Actors - Supervising
„Parents“ are responsble for
handling „children“'s failures
The recursive structure
then allows to handle
failure at the right
level
different supervision strategies
can be configured: resume,
restart, stop, escalate
Actors
Location Transparent & Distributable
If an actor
communicates
with another one
inside the same
JVM or
remotelly is just
a matter of
configuration program just
holds an Actor's
reference, not
the instance! this
makes possible to
deploy actors
wherever you
want (local,
remote)
all messages
must be
serializable
Actors - Isolation
Actors run completely isolated - the only
way to communicate with them is by
sending messages
Actors – JVM Implementations
http://akka.io/
Akka
● many actors share one thread. one actor typically weights
300 bytes
● an actor only receives one message at a time – while
processing the message, the actor is „thread safe“
(subsequent processing rule)
● router actor: Creates children, and forwards messages to
the children (kind of load balancer)
● distributed by default: everything is dessigned to work
on a distributed environment
● prefer inmutable messages
Akka Persistence
● Command Sourcing: "At least once"
guarantees
– event is persisted before it enters the system (it's
not even validated)
● Event Sourcing: "At most once" guarantees
– event is persisted afterwards (first, the sate of the
actor is changed, and then the event is persisted) -
decouples event changes from side effects
END
1 of 77

Recommended

The Future of Futures - A Talk About Java 8 CompletableFutures by
The Future of Futures - A Talk About Java 8 CompletableFuturesThe Future of Futures - A Talk About Java 8 CompletableFutures
The Future of Futures - A Talk About Java 8 CompletableFuturesHaim Yadid
10.9K views46 slides
Concurrency Utilities in Java 8 by
Concurrency Utilities in Java 8Concurrency Utilities in Java 8
Concurrency Utilities in Java 8Martin Toshev
1.5K views46 slides
CompletableFuture by
CompletableFutureCompletableFuture
CompletableFuturekoji lin
9.2K views46 slides
Concurrency with java by
Concurrency with javaConcurrency with java
Concurrency with javaHoang Nguyen
366 views51 slides
Java concurrency - Thread pools by
Java concurrency - Thread poolsJava concurrency - Thread pools
Java concurrency - Thread poolsmaksym220889
5.6K views35 slides
Functional Reactive Programming / Compositional Event Systems by
Functional Reactive Programming / Compositional Event SystemsFunctional Reactive Programming / Compositional Event Systems
Functional Reactive Programming / Compositional Event SystemsLeonardo Borges
18K views72 slides

More Related Content

What's hot

Fork Join (BeJUG 2012) by
Fork Join (BeJUG 2012)Fork Join (BeJUG 2012)
Fork Join (BeJUG 2012)Sander Mak (@Sander_Mak)
2.1K views42 slides
Parallel streams in java 8 by
Parallel streams in java 8Parallel streams in java 8
Parallel streams in java 8David Gómez García
10.2K views42 slides
DjangoCon US 2011 - Monkeying around at New Relic by
DjangoCon US 2011 - Monkeying around at New RelicDjangoCon US 2011 - Monkeying around at New Relic
DjangoCon US 2011 - Monkeying around at New RelicGraham Dumpleton
1.7K views67 slides
Fork/Join for Fun and Profit! by
Fork/Join for Fun and Profit!Fork/Join for Fun and Profit!
Fork/Join for Fun and Profit!Sander Mak (@Sander_Mak)
1.7K views23 slides
PyCon AU 2012 - Debugging Live Python Web Applications by
PyCon AU 2012 - Debugging Live Python Web ApplicationsPyCon AU 2012 - Debugging Live Python Web Applications
PyCon AU 2012 - Debugging Live Python Web ApplicationsGraham Dumpleton
11.4K views44 slides
Advanced task management with Celery by
Advanced task management with CeleryAdvanced task management with Celery
Advanced task management with CeleryMahendra M
63.2K views26 slides

What's hot(20)

DjangoCon US 2011 - Monkeying around at New Relic by Graham Dumpleton
DjangoCon US 2011 - Monkeying around at New RelicDjangoCon US 2011 - Monkeying around at New Relic
DjangoCon US 2011 - Monkeying around at New Relic
Graham Dumpleton1.7K views
PyCon AU 2012 - Debugging Live Python Web Applications by Graham Dumpleton
PyCon AU 2012 - Debugging Live Python Web ApplicationsPyCon AU 2012 - Debugging Live Python Web Applications
PyCon AU 2012 - Debugging Live Python Web Applications
Graham Dumpleton11.4K views
Advanced task management with Celery by Mahendra M
Advanced task management with CeleryAdvanced task management with Celery
Advanced task management with Celery
Mahendra M63.2K views
How NOT to write in Node.js by Piotr Pelczar
How NOT to write in Node.jsHow NOT to write in Node.js
How NOT to write in Node.js
Piotr Pelczar17K views
Real world functional reactive programming by Eric Polerecky
Real world functional reactive programmingReal world functional reactive programming
Real world functional reactive programming
Eric Polerecky2.3K views
Fork and join framework by Minh Tran
Fork and join frameworkFork and join framework
Fork and join framework
Minh Tran1.9K views
Non Blocking I/O for Everyone with RxJava by Frank Lyaruu
Non Blocking I/O for Everyone with RxJavaNon Blocking I/O for Everyone with RxJava
Non Blocking I/O for Everyone with RxJava
Frank Lyaruu2K views
The Road To Reactive with RxJava JEEConf 2016 by Frank Lyaruu
The Road To Reactive with RxJava JEEConf 2016The Road To Reactive with RxJava JEEConf 2016
The Road To Reactive with RxJava JEEConf 2016
Frank Lyaruu749 views
Functional Reactive Programming in Clojurescript by Leonardo Borges
Functional Reactive Programming in ClojurescriptFunctional Reactive Programming in Clojurescript
Functional Reactive Programming in Clojurescript
Leonardo Borges11.6K views
Gevent what's the point by seanmcq
Gevent what's the pointGevent what's the point
Gevent what's the point
seanmcq6.9K views
Asynchronous CompletableFuture Presentation by László-Róbert Albert @Crossover by Crossover Romania
Asynchronous CompletableFuture Presentation by László-Róbert Albert @CrossoverAsynchronous CompletableFuture Presentation by László-Róbert Albert @Crossover
Asynchronous CompletableFuture Presentation by László-Róbert Albert @Crossover
Crossover Romania139 views
Akka Cluster in Java - JCConf 2015 by Jiayun Zhou
Akka Cluster in Java - JCConf 2015Akka Cluster in Java - JCConf 2015
Akka Cluster in Java - JCConf 2015
Jiayun Zhou4K views
Javascript Promises/Q Library by async_io
Javascript Promises/Q LibraryJavascript Promises/Q Library
Javascript Promises/Q Library
async_io28.8K views

Viewers also liked

面對移動化App挑戰的架構設計 by
面對移動化App挑戰的架構設計面對移動化App挑戰的架構設計
面對移動化App挑戰的架構設計Clark
570 views33 slides
Threads and concurrency in Java 1.5 by
Threads and concurrency in Java 1.5Threads and concurrency in Java 1.5
Threads and concurrency in Java 1.5Peter Antman
1.9K views17 slides
Introduction of Android Camera1 by
Introduction of Android Camera1Introduction of Android Camera1
Introduction of Android Camera1Booch Lin
4.8K views24 slides
JAVA GUI PART III by
JAVA GUI PART IIIJAVA GUI PART III
JAVA GUI PART IIIOXUS 20
2K views21 slides
Asynchronous API in Java8, how to use CompletableFuture by
Asynchronous API in Java8, how to use CompletableFutureAsynchronous API in Java8, how to use CompletableFuture
Asynchronous API in Java8, how to use CompletableFutureJosé Paumard
25.1K views117 slides
Node.js and Selenium Webdriver, a journey from the Java side by
Node.js and Selenium Webdriver, a journey from the Java sideNode.js and Selenium Webdriver, a journey from the Java side
Node.js and Selenium Webdriver, a journey from the Java sideMek Srunyu Stittri
25.9K views56 slides

Viewers also liked(9)

面對移動化App挑戰的架構設計 by Clark
面對移動化App挑戰的架構設計面對移動化App挑戰的架構設計
面對移動化App挑戰的架構設計
Clark 570 views
Threads and concurrency in Java 1.5 by Peter Antman
Threads and concurrency in Java 1.5Threads and concurrency in Java 1.5
Threads and concurrency in Java 1.5
Peter Antman1.9K views
Introduction of Android Camera1 by Booch Lin
Introduction of Android Camera1Introduction of Android Camera1
Introduction of Android Camera1
Booch Lin4.8K views
JAVA GUI PART III by OXUS 20
JAVA GUI PART IIIJAVA GUI PART III
JAVA GUI PART III
OXUS 202K views
Asynchronous API in Java8, how to use CompletableFuture by José Paumard
Asynchronous API in Java8, how to use CompletableFutureAsynchronous API in Java8, how to use CompletableFuture
Asynchronous API in Java8, how to use CompletableFuture
José Paumard25.1K views
Node.js and Selenium Webdriver, a journey from the Java side by Mek Srunyu Stittri
Node.js and Selenium Webdriver, a journey from the Java sideNode.js and Selenium Webdriver, a journey from the Java side
Node.js and Selenium Webdriver, a journey from the Java side
Mek Srunyu Stittri25.9K views
Reactive Programming in Java 8 with Rx-Java by Kasun Indrasiri
Reactive Programming in Java 8 with Rx-JavaReactive Programming in Java 8 with Rx-Java
Reactive Programming in Java 8 with Rx-Java
Kasun Indrasiri30.2K views
Concurrency: The Good, The Bad and The Ugly by legendofklang
Concurrency: The Good, The Bad and The UglyConcurrency: The Good, The Bad and The Ugly
Concurrency: The Good, The Bad and The Ugly
legendofklang39.3K views

Similar to Concurrent Programming in Java

Java util concurrent by
Java util concurrentJava util concurrent
Java util concurrentRoger Xia
2.3K views62 slides
.NET Multithreading/Multitasking by
.NET Multithreading/Multitasking.NET Multithreading/Multitasking
.NET Multithreading/MultitaskingSasha Kravchuk
965 views31 slides
Effective java item 80 and 81 by
Effective java   item 80 and 81Effective java   item 80 and 81
Effective java item 80 and 81Isaac Liao
136 views28 slides
Java Concurrency, Memory Model, and Trends by
Java Concurrency, Memory Model, and TrendsJava Concurrency, Memory Model, and Trends
Java Concurrency, Memory Model, and TrendsCarol McDonald
7.7K views62 slides
Tech Talks_04.07.15_Session 3_Martin Toshev_Concurrency Utilities In Java 8 by
Tech Talks_04.07.15_Session 3_Martin Toshev_Concurrency Utilities In Java 8Tech Talks_04.07.15_Session 3_Martin Toshev_Concurrency Utilities In Java 8
Tech Talks_04.07.15_Session 3_Martin Toshev_Concurrency Utilities In Java 8EPAM_Systems_Bulgaria
292 views46 slides
Java Concurrency by
Java ConcurrencyJava Concurrency
Java ConcurrencyCarol McDonald
3.9K views41 slides

Similar to Concurrent Programming in Java(20)

Java util concurrent by Roger Xia
Java util concurrentJava util concurrent
Java util concurrent
Roger Xia2.3K views
.NET Multithreading/Multitasking by Sasha Kravchuk
.NET Multithreading/Multitasking.NET Multithreading/Multitasking
.NET Multithreading/Multitasking
Sasha Kravchuk965 views
Effective java item 80 and 81 by Isaac Liao
Effective java   item 80 and 81Effective java   item 80 and 81
Effective java item 80 and 81
Isaac Liao136 views
Java Concurrency, Memory Model, and Trends by Carol McDonald
Java Concurrency, Memory Model, and TrendsJava Concurrency, Memory Model, and Trends
Java Concurrency, Memory Model, and Trends
Carol McDonald7.7K views
Tech Talks_04.07.15_Session 3_Martin Toshev_Concurrency Utilities In Java 8 by EPAM_Systems_Bulgaria
Tech Talks_04.07.15_Session 3_Martin Toshev_Concurrency Utilities In Java 8Tech Talks_04.07.15_Session 3_Martin Toshev_Concurrency Utilities In Java 8
Tech Talks_04.07.15_Session 3_Martin Toshev_Concurrency Utilities In Java 8
Concurrency with side-effects – cats way by stasimus
Concurrency with side-effects – cats wayConcurrency with side-effects – cats way
Concurrency with side-effects – cats way
stasimus1.2K views
What is new in java 8 concurrency by kshanth2101
What is new in java 8 concurrencyWhat is new in java 8 concurrency
What is new in java 8 concurrency
kshanth2101458 views
Async and parallel patterns and application design - TechDays2013 NL by Arie Leeuwesteijn
Async and parallel patterns and application design - TechDays2013 NLAsync and parallel patterns and application design - TechDays2013 NL
Async and parallel patterns and application design - TechDays2013 NL
Arie Leeuwesteijn5.2K views
Programming with Threads in Java by koji lin
Programming with Threads in JavaProgramming with Threads in Java
Programming with Threads in Java
koji lin2.8K views
Modern Java Concurrency by Ben Evans
Modern Java ConcurrencyModern Java Concurrency
Modern Java Concurrency
Ben Evans2.5K views
Structured concurrency with Kotlin Coroutines by Vadims Savjolovs
Structured concurrency with Kotlin CoroutinesStructured concurrency with Kotlin Coroutines
Structured concurrency with Kotlin Coroutines
Vadims Savjolovs261 views
Looming Marvelous - Virtual Threads in Java Javaland.pdf by jexp
Looming Marvelous - Virtual Threads in Java Javaland.pdfLooming Marvelous - Virtual Threads in Java Javaland.pdf
Looming Marvelous - Virtual Threads in Java Javaland.pdf
jexp118 views
The Mayans Lost Guide to RxJava on Android by Fernando Cejas
The Mayans Lost Guide to RxJava on AndroidThe Mayans Lost Guide to RxJava on Android
The Mayans Lost Guide to RxJava on Android
Fernando Cejas1.5K views

Recently uploaded

hamro digital logics.pptx by
hamro digital logics.pptxhamro digital logics.pptx
hamro digital logics.pptxtupeshghimire
10 views36 slides
The Dark Web : Hidden Services by
The Dark Web : Hidden ServicesThe Dark Web : Hidden Services
The Dark Web : Hidden ServicesAnshu Singh
16 views24 slides
How to think like a threat actor for Kubernetes.pptx by
How to think like a threat actor for Kubernetes.pptxHow to think like a threat actor for Kubernetes.pptx
How to think like a threat actor for Kubernetes.pptxLibbySchulze1
7 views33 slides
Affiliate Marketing by
Affiliate MarketingAffiliate Marketing
Affiliate MarketingNavin Dhanuka
18 views30 slides
ATPMOUSE_융합2조.pptx by
ATPMOUSE_융합2조.pptxATPMOUSE_융합2조.pptx
ATPMOUSE_융합2조.pptxkts120898
35 views70 slides
Marketing and Community Building in Web3 by
Marketing and Community Building in Web3Marketing and Community Building in Web3
Marketing and Community Building in Web3Federico Ast
15 views64 slides

Recently uploaded(6)

The Dark Web : Hidden Services by Anshu Singh
The Dark Web : Hidden ServicesThe Dark Web : Hidden Services
The Dark Web : Hidden Services
Anshu Singh16 views
How to think like a threat actor for Kubernetes.pptx by LibbySchulze1
How to think like a threat actor for Kubernetes.pptxHow to think like a threat actor for Kubernetes.pptx
How to think like a threat actor for Kubernetes.pptx
LibbySchulze17 views
ATPMOUSE_융합2조.pptx by kts120898
ATPMOUSE_융합2조.pptxATPMOUSE_융합2조.pptx
ATPMOUSE_융합2조.pptx
kts12089835 views
Marketing and Community Building in Web3 by Federico Ast
Marketing and Community Building in Web3Marketing and Community Building in Web3
Marketing and Community Building in Web3
Federico Ast15 views

Concurrent Programming in Java

  • 2. Index ● Concurrency ● Threads ● Executors ● ForkJoin ● Paralell Streams ● CompletableFuture ● RXJava ● Actors
  • 3. Concurrency? „a property of systems in which several computations are executing simultaneously, and potentially interacting with each other“ http://en.wikipedia.org/wiki/Concurrency_(computer_science)
  • 6. Amdahl's Law The speedup of a program using multiple processors in parallel computing is limited by the sequential fraction of the program. For example, if 95% of the program can be parallelized, the theoretical maximum speedup using parallel computing would be 20× as shown in the diagram, no matter how many processors are used.
  • 8. Java1.0 - Threads public class TestRunnable implements Runnable { public void run() { //do something } } Thread t = new Thread(new TestRunnable()); t.start(); //Thread starts t.join(1000); //Waits 1 second until thread finishes t.isAlive(); //checks if thread is alive t.interrupt(); // stops thread
  • 9. Communication betwen Threads ● Threads communicate by sharing access to fields ● This kind of communication can lead to: – Thread interference: sequence of steps overlap, leading to wrong results. – Memory consistency errors: changes to objects are not immediatelly visible to other threads
  • 10. Thread Interference – sequence of steps overlap, leading to wrong results
  • 11. Memory Consistency Errors //thread A increments counter counter++; // counter is shared by 2 threads int counter = 0; Thread A Thread B //thread B prints out counter, // right after A's change System.out.println(counter); Which value prints out B? there's no guarantee that thread A's change to counter will be visible to thread B, unless the programmer has established a happens-before relationship between these two statements
  • 12. Threads ● To prevent Thread Interference and Memory Consistency errors, we use synchronization, that can introduce Thread Contention – Deadlocks: threads wait for each other forever. – Starvation: thread blocks for a long time, because synchronized block takes too much time to execute. – Livelocks: threads introduce logic to avoid deadlocks, but they fail reapeatedly.
  • 14. Thread Problems ● Expensive to create – CPU + RAM (around. 512Kb per Thread!) ● Performance overhead when CPU does context switching (switching between threads) – Everytime a thread blocks or sleeps, context is switched ● Memory is shared around threads – Problem with concurrent access to shared objects ● Difficult to control flow ● Difficult to control the number of threads started ● Locks to control access to shared resources – Can introduce thread contention
  • 15. Java5 – Concurrency Enhancements ● Atomic Numbers (AtomicInteger): get and increment a value atomically ● Concurrent Collections (e.g. ConcurrentHashMap): supports concurrent reads and updates ● ExecutorService ● Futures
  • 16. ExecutorService ● Takes care of executing (and controlling the execution) of asynchronous tasks ● Configurable Thread Pools – CorePoolSize – MaximumPoolSize, – KeepAliveTime – ThreadFactory – RejectedExecutionHandler ● Predefined Executors – Cached – Fixed – Scheduled – SingleThreaded http://blog.jessitron.com/2014/01/choosing-executorservice.html
  • 17. Executor Executor executor = new ThreadPoolExecutor(...) executor.execute(new Runnable() { public void run() { //execute task } }); ● Parent Interface of ExecutorService ● Just provides one method: execute
  • 18. ExecutorService //creates the executor service ExecutorService executorService = Executors.newFixedThreadPool(5); //submits a task to be executed asynchronously Future<String> future = executorService.submit(new Callable<String>() { @Override public String call() throws Exception { return "hi"; } }); //blocks until the result is ready String message = future.get(); // no more executions will be accepted executorService.shutdown(); // blocks until all tasks have completed execution executorService.awaitTermination(1, TimeUnit.SECONDS);
  • 19. ExecutorService + Callable + Future //submits a task to be executed asynchronously Future<String> future = executorService.submit(new Callable<String>() { @Override public String call() throws Exception { return "hi"; } }); //blocks until the result is ready String message = future.get(); Blocks until result is ready (thread has finished) ● Callable allows threads to return a result ● Future holds the result of the asynchronous computation
  • 20. Future methods ● get() – BLOCKS until result is ready ● get(timeout) throws TimeoutException ● cancel(mayInterruptIfRunning) – If task has not started, it will not be started – Otherwise, if mayInterruptIfRunning is true, it will Interrupt ● isDone() ● isCancelled()
  • 21. ExecutorService – more methods ● List<Future> invokeAll(Collection <Callable> Tasks – Executes all tasks, and returns when ALL have completed execution ● Object invokeAny(Collection<Callable>) – Starts execution of all tasks and returns the result of one finished task. Tasks that have not completed, are cancelled. ● invoke* and await* methods support timeout parameters. If task doesn't finish on time, method still returns
  • 22. ExecutorService - Pros ● Now we can: – Cache Threads => less overhead – Control Size of Pool => less risk of OOM – Easily retrieve values of asynchronous computation (Future) – Submit multiple tasks simultaneously
  • 23. Executors - Cons ● How to control multiple executions? Future<String> fA = executorService.submit(....); Future<String> fB = executorService.submit(....); Future<String> fC = executorService.submit(....); String a = fA.get(); String b = fB.get(); String c = fC.get(); What if fB and fC are ready before fA?
  • 24. Executors - Cons ● How to nest calls? Future<String> fA = executorService.submit(new RemoteCall()); Future<String> fB = executorService.submit(new RemoveCallWithParam(fA.get()); ….......... String a = fA.get(); String a = fB.get(); fA.get() BLOCKS!
  • 25. Callbacks executorService.execute(new RemoteCall(new Callback() { public void notify(Object param) { //remote call has finished – do something } })); //continue doing something interface Callback { void notify(Object param); } class RemoteCall implements Runnable { private Callback callback; public RemoteCall(Callback callback) { this.callback = callback; } public void run() { //execute remote call callback.notify(param) } } when RemoteCall finishes it notifies the registered callback no blocking
  • 26. Executors - Cons ● Futures block and are difficult to nest ● Callbacks do not block, but do not solve the problem of nested composition
  • 27. Java7 - ForkJoin ● Implementation of ExecutorService ● Aims to utilize a multi-core architecture at a maximum ● Uses a work-stealing algorithm: if a worker runs out of tasks, can steal work from others ● Useful for recursive tasks if (my portion of the work is small enough) do the work directly else split my work into two pieces invoke the two pieces and wait for the results
  • 29. public class ForkSum extends RecursiveAction { private final int[] array; private final int start; private final int end; private final AtomicInteger result; public ForkSum(int[] array, int start, int end, AtomicInteger result) { super(); this.array = array; this.start = start; this.end = end; this.result = result; } private void computeDirectly() { int partialSum = 0; for (int i = start; i < end; i++) { partialSum += array[i]; } result.addAndGet(partialSum); } @Override protected void compute() { if ((start - end) < 10) { computeDirectly(); } else { int delta = (end - start) / 2; ForkSum a = new ForkSum(array, start, start + delta, result); ForkSum b = new ForkSum(array, start + delta + 1, end, result); invokeAll(a, b); } }
  • 30. int[] array = new int[2046]; Arrays.fill(array, 2); AtomicInteger result = new AtomicInteger(0); ForkSum forkSum = new ForkSum(array, 0, array.length, result); ForkJoinPool pool = new ForkJoinPool(); pool.invoke(forkSum); System.out.println(forkSum.getResult()); ForkJoinPool uses work stealing We can set the „parallelism level“ to ForkJoinPool (defaults to number of processors)
  • 31. Java7 - ForkJoin ● Only really useful for recursive tasks ● Does not help with the problems with had in the Executors (blocking & nested composition)
  • 32. Java8 – Streams // PROBLEM: Perform a time-intensive computation // to each element of the list List<Integer> col = Arrays.asList(1, 2, 3); // Procedural Solution List<Integer> colResult = new ArrayList<Integer>(); for (Integer i : col) { colResult.add(expensiveOperation(i)); } //Functional Solution: use map() with a HighOrderFunction List<Integer> colResultF = col.stream().map(i -> expensiveOperation(i)) .collect(Collectors.toList());
  • 33. Java8 – Parallel Streams //Functional Solution+: // parallelize the stream // and use map() with a HighOrderFunction List<Integer> colResultFP = col.parallelStream().map(i -> expensiveOperation(i)) .collect(Collectors.toList());
  • 34. Java8 - CompletableFuture ● Futures with – Callbacks – Transformations – Possibility to explicitly set a value in the Future (i.e. Promise)
  • 35. Completing a CompletableFuture //CALLEE public CompletableFuture<String> doSomething() { final CompletableFuture<String> future = createFuture(); // do something (synch or asynch) // when ready, call future.complete("hi"); // that will unlock the clients waiting for the future return future; } //CALLER CompletableFuture<String> cf = doSomething(); // Blocks until callee „completes“ the future with f.complete String result = cf.get(); will normally be executed asynch blocks
  • 36. How to get a value from a CompletableFuture ● get() – BLOCKS until the value is present, and returns it ● get(timeout, timeoutUnit) – BLOCKS until the value is present, or the timeout has been reached. If the later , a TimeoutException is thrown ● getNow(valueIfAbsent) – Doesn't block! if the value is present, it returns it; otherwise, the valueIfAbsent param (default) is returned
  • 37. How to complete a CompletableFuture ● complete(value) – completes ok with the value – only the first call takes effect – subsequent calls are ignored ● completeExceptionally(ex) – completes with exception – get() will throw an exception in the caller ● cancel() – completes with a CancellationException
  • 38. Completing a CompletableFuture ● Why is this useful? – We can execute a task sometimes in synchronous, and sometimes in asynchronous mode, without having to change the client. We just deliver a CompletableFuture, and the implementation decides the execution mode.
  • 39. Creating a CompletableFuture // <Java7 CompletableFuture<String> f = CompletableFuture.supplyAsync( new Supplier<String>() { @Override public String get() { // perform task return "hi"; } }, executorService); // OR Using Lambdas CompletableFuture<String> ft = CompletableFuture.supplyAsync( () -> "hi", executorService); Supplier is a functional interface Similar to Callable if no executor is provided, the ForkJoinPool.commonPool will be used
  • 40. Creating a CompletableFuture ● CompletableFuture<T> CompletableFuture.supplyAsync(supplier<T>, executor> – If no executor is provided, a Common Static pool for all tasks called ForkJoinPool.commonPool wil be used. This executor cannot be shutdown ● CompletableFuture<Void> CompletableFuture.runAsync(runnable, exec) – Accepts a Runnable instead of a Supplier → no value will be returned
  • 41. CompletableFuture Registering Callbacks ● .thenApply → registers a callback, that will be executed asynchronously when the future is ready. It uses the same thread that executed the future! ● .thenApplyAsynch → same as .thenApply, but the callback will be executed in a different thread than the one that completed the future map in fp terms
  • 42. CompletableFuture - Nesting and Composing CompletableFuture<Order> f1 = persistOrder(o); CompletableFuture<Order> f2 = f1.thenApply(o → transferOrderToContractor(o)); CompletableFuture<Order> f3 = f2.thenApply(o → updateSearchIndex(o)); CompletableFuture<Order> f4 = f3.thenApply(o → sendMonitoringInfo(o)); //OR, in a line: CompletableFuture<Order> f1 = persistOrder(o) .thenApply(o → transferOrderToContractor(o)) .thenApply(o → updateSearchIndex(o)) .thenApply(o → sendMonitoringInfo(o)); thenApply doesn't block! operations are executed in order, but do not block map in fp terms
  • 43. Set<Order> ordersToProcess = ….; ordersToProcess.stream().map(o → persistOrder(o) .thenApply(o → transferOrderToContractor(o)) .thenApply(o → updateSearchIndex(o)) .thenApply(o → sendMonitoringInfo(o))); CompletableFuture Multiple Items
  • 44. CompletableFuture<Order> f1 = persistOrder(o); CompletableFuture<Order> f2 = f1.thenApply(o → transferOrderToContractor(o)); f2.thenAccept(o → logger.debug(„Order „ + o + „ succesfully processed“); CompletableFuture Consuming Final Value ● thenAccept → accepts a function that will be executed when the CompletableFuture has finished
  • 45. CompletableFuture Error Handling ● exceptionally → accepts a function with the exception as parameter ● handle → accepts a function with both the normal result AND the exception as parameter, but only one of them is set CompletableFuture<Order> f1 = persistOrderAsynch(o); f1.exceptionally(e -> sendAlertMessage(e)); //OR f1.handle((order, ex) -> { if (ex != null) { sendAlertMessage(ex); return null; } else { logger.info("Order persisted: " + order); return order; } });
  • 46. CompletableFuture Composing ● CompletableFutures provides functions to combine multiple futures together ● thenCompose → same as thenApply, but the function that accepts returns a CompletableFuture private CompletableFuture<Status> sendData(String data) {…}; CompletableFuture<String> f1 = retrieveData(); CompletableFuture<Status> fs = f1.thenCompose(data → sendData(data)); flatMap in fp terms
  • 47. CompletableFuture Combining ● thenCombine → executes a callback when 2 completableFutures finish CompletableFuture<Address> f1 = retrieveContactAddress(contact); CompletableFuture<Identification> f2 = retrieveContactIdentification(contact); CompletableFuture<String> fs = f1.thenCombine(f2, (address, id) → peristContactData(address id));
  • 48. CompletableFuture Accepting one ● acceptEither → returns the future that completes first ● applyToEither → same than accept either, but it executes a callback when the first future completes CompletableFuture<Contact> f1 = searchContactInDB(name); CompletableFuture<Contact> f2 = searchContactInIndex(name); CompletableFuture<Contact> fs = f1.applyToEither(f2, c → sysout(„Contact found: „ + c); we do not care who finishes first. Just want one
  • 49. CompletableFuture Static Methods ● anyOf → static method, similar to acceptEither, that returns the future that completes first ● allOf → static method, that returns a future that will complete when all futures complete CompletableFuture<Contact> f1 = searchContactInDB(name); CompletableFuture<Contact> f2 = searchContactInIndex(name); CompletableFuture<Contact> fs = CompletableFuture.anyOf(f1, f2); we do not care who finishes first. Just want one
  • 50. CompletablFuture - Problems ● Transactions – In a EE App Server, we can use the ManagedExecutorService – Tasks submitted via ManagedExecutorService can get components @Injected (e.g. EntitiyManager) @Resource ManagedExecutorService managedExecutorService;
  • 51. RX Java ● Java Implementation of ReactiveExtensions (.NET) ● Library for composing asynchronous and event-based programs ● Introduces the Observable type (extension the Observer GOF Pattern) – consumer subscribes to an event, and producer pushes data when available ● Can be seen as an Iterator that, instead of pulling, gets the data pushed. ● Futures work on single items – Observables work on multiple items
  • 52. event Iterable (pull) Observable (push) retrieve data T next() onNext(T) discover error throws Exception onError(Exception) complete returns onCompleted() Iterable vs Observable An Observable is the asynchronous/push "dual" to the synchronous/pull Iterable
  • 53. 4 3 2 1…. PULL PUSH 4 3 2 1….
  • 54. Observable<String> homeMadeSyncObservable = Observable.create(new OnSubscribe<String>() { @Override public void call(Subscriber<? super String> subscriber) { subscriber.onNext("1"); subscriber.onNext("2"); subscriber.onNext("3"); subscriber.onCompleted(); } }); Creating Observables - Sync Observable<String> observable = Observable.from(Arrays.asList("1", "2", "3")); ● Observable.create • Observable.from
  • 55. Observable.from(numbers).subscribe(n -> System.out.println("value received: " + n), t -> System.out.println("Exception thrown: " + t), () -> System.out.println("observable completed") ); Subscribing to Observables ● subscribe function accepts three parameters in the form of functions – onNext → function to be called when a value is emitted. The value is passed as parameter to the function. – onError → function to be called when an exception is emitted. The exception is passed as parameter to the function – onComplete → function to be called when the observable doesn't have any more value to emit (has finished). This function doesn't accept any parameter.
  • 56. Holly Lambdas! Observable.from(numbers).subscribe(new Action1<Integer>() { @Override public void call(Integer n) { System.out.println("value received: " + n); } }, new Action1<Throwable>() { @Override public void call(Throwable t) { System.out.println("Exception thrown: " + t); } }, new Action0() { @Override public void call() { System.out.println("observable completed"); } }); Observable.from(numbers).subscribe(n -> System.out.println("value received: " + n), t -> System.out.println("Exception thrown: " + t), () -> System.out.println("observable completed") );Java8 Java7
  • 57. Subscribing to Observables ● Instead of passing three functions to subscribe, we can implement the Observer Interface. public interface Observer<T> { /** * Notifies the Observer that the {@link Observable} has finished sending push-based notifications. public abstract void onCompleted(); /** * Notifies the Observer that the {@link Observable} has experienced an error condition. */ public abstract void onError(Throwable e); /** * Provides the Observer with new data. */ public abstract void onNext(T t); }
  • 58. Subscribing to Observables ● or, if we are just interested in the values, we can just „listen“ to the emitted values by passing just the first function Observable<Integer> observable = Observable.from(1, 2, 3); observable.subscribe(t -> System.out.println(t));
  • 59. 4 3 2 1…. OBSERVABLE OBSERVER Observable.from(Arrays.asList("1", "2", "3")); obs.subscribe (n -> echo("value received: " + n), t -> echo("Exception thrown: " + t), () -> echo("observable completed") );
  • 60. Subscriptions ● Observable.subscribe() returns a Subscription object, that offers two methods: /** * Stop receiving notifications on the {@link Subscriber} that was registered when this Subscription was received. * <p> * This allows unregistering an {@link Subscriber} before it has finished receiving all events (ie. before onCompleted is called). */ public void unsubscribe(); public boolean isUnsubscribed(); ● If we unsubscribe, the Observer will stop receiving events
  • 61. Observable<String> homeMadeAsyncObservable = Observable.create(new OnSubscribe<String>() { @Override public void call(Subscriber<? super String> subscriber) { final Thread thread = new Thread(() -> { subscriber.onNext("1"); subscriber.onNext("2"); subscriber.onNext("3"); subscriber.onCompleted(); }); thread.start(); } }); Creating Observables - Async ● Observable.create – Async with Thread
  • 62. final ExecutorService threadPool = Executors.newCachedThreadPool(); Observable<String> observableWithExecutor = Observable.create(new OnSubscribe<String>() { @Override public void call(Subscriber<? super String> subscriber) { threadPool.execute(() -> subscriber.onNext("a")); threadPool.execute(() -> subscriber.onNext("b")); threadPool.execute(() -> subscriber.onNext("c")); try { threadPool.shutdown(); threadPool.awaitTermination(2, TimeUnit.SECONDS); subscriber.onCompleted(); } catch (InterruptedException e) { subscriber.onError(e); } } }); Creating Observables - Async ● Observable.create – Async with Executors
  • 63. Transforming Observables ● map() and flatMap() → same as thenApply and thenCompose in CompletableFuture observable.map( n -> n + 1) → Observable(2, 3, 4) observable.flatMap( n -> Observable.from(n+1)) → Observable(2, 3, 4) ● groupBy, scan, pivot, buffer, window... Observable<Integer> observable = Observable.from(1, 2, 3);
  • 64. Filtering Observables List<String> names = Arrays.asList("Stefan", "Sebastian", "Ruben", "Robert", "Harald"); Observable.from(names).filter(s -> s.startsWith("S")); → Observable(„Stefan“, „Sebastian“) Observable.from(names).take(2)); → Observable(„Stefan“, „Sebastian“) takeLast, first, elementAt, sample, timeout, distinct, ofType, ...
  • 65. Combining Observables zip, join, paralellMerge, combineLatest...
  • 66. MUCH more on RXJava https://github.com/Netflix/RxJava/wiki/
  • 67. Functional Reactive Programming (Netflix) ● All return types are Observable. The service layer decides to: – return immediately with a value (i.e. value in cache) – or block until result available – or return immediately and perform execution asynchronously
  • 68. Actors ● originated in 1973 ● objects that encapsulate state and behaviour ● very lightweight concurrent entities ● process messages asynchronously using an event-driven receive loop ● they communicate only via messages ● raise the abstraction level to work with events flowing through the system
  • 70. Actors - Supervising Actors build „trees of Actors“, forming a hierarchical structure each actor has exactly one supervisor, which is the actor that created it tasks are split up and delegated until they become small enough to be handled in one piece
  • 71. Actors - Supervising „Parents“ are responsble for handling „children“'s failures The recursive structure then allows to handle failure at the right level different supervision strategies can be configured: resume, restart, stop, escalate
  • 72. Actors Location Transparent & Distributable If an actor communicates with another one inside the same JVM or remotelly is just a matter of configuration program just holds an Actor's reference, not the instance! this makes possible to deploy actors wherever you want (local, remote) all messages must be serializable
  • 73. Actors - Isolation Actors run completely isolated - the only way to communicate with them is by sending messages
  • 74. Actors – JVM Implementations http://akka.io/
  • 75. Akka ● many actors share one thread. one actor typically weights 300 bytes ● an actor only receives one message at a time – while processing the message, the actor is „thread safe“ (subsequent processing rule) ● router actor: Creates children, and forwards messages to the children (kind of load balancer) ● distributed by default: everything is dessigned to work on a distributed environment ● prefer inmutable messages
  • 76. Akka Persistence ● Command Sourcing: "At least once" guarantees – event is persisted before it enters the system (it's not even validated) ● Event Sourcing: "At most once" guarantees – event is persisted afterwards (first, the sate of the actor is changed, and then the event is persisted) - decouples event changes from side effects
  • 77. END

Editor's Notes

  1. The speedup of a program using multiple processors in parallel computing is limited by the sequential fraction of the program. For example, if 95% of the program can be parallelized, the theoretical maximum speedup using parallel computing would be 20× as shown in the diagram, no matter how many processors are used.