SlideShare a Scribd company logo
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

More Related Content

PDF
Concurrency Utilities in Java 8
Martin Toshev
 
PDF
Deep Dive Java 17 Devoxx UK
José Paumard
 
PPTX
Concurrency with java
Hoang Nguyen
 
PDF
Introduction to Spring Boot
Trey Howard
 
PPSX
Elements of Java Language
Hitesh-Java
 
PPTX
Spring boot
Pradeep Shanmugam
 
PDF
From Java 11 to 17 and beyond.pdf
José Paumard
 
PPTX
Spring data jpa
Jeevesh Pandey
 
Concurrency Utilities in Java 8
Martin Toshev
 
Deep Dive Java 17 Devoxx UK
José Paumard
 
Concurrency with java
Hoang Nguyen
 
Introduction to Spring Boot
Trey Howard
 
Elements of Java Language
Hitesh-Java
 
Spring boot
Pradeep Shanmugam
 
From Java 11 to 17 and beyond.pdf
José Paumard
 
Spring data jpa
Jeevesh Pandey
 

What's hot (20)

PDF
[KGC 2012]Boost.asio를 이용한 네트웍 프로그래밍
흥배 최
 
PDF
Multi threading
Ravi Kant Sahu
 
PDF
Enumeration in Java Explained | Java Tutorial | Edureka
Edureka!
 
PPTX
Spring boot
Gyanendra Yadav
 
PDF
Java 17
Mutlu Okuducu
 
PDF
Spring Boot
Jaran Flaath
 
PDF
Spring boot jpa
Hamid Ghorbani
 
PPSX
Spring - Part 2 - Autowiring, Annotations, Java based Configuration - slides
Hitesh-Java
 
PPTX
20.3 Java encapsulation
Intro C# Book
 
PDF
Devoxx France 2023 - Les nouveautés de Java 19 et 20
Jean-Michel Doudoux
 
PPTX
Java 8 Lambda and Streams
Venkata Naga Ravi
 
PDF
Lambda Expressions in Java | Java Lambda Tutorial | Java Certification Traini...
Edureka!
 
PPT
Spring Framework
nomykk
 
PPTX
Java file
sonnetdp
 
PPTX
Multithreading in java
Arafat Hossan
 
PPTX
Java Spring Framework
Mehul Jariwala
 
PPTX
Spring Boot and REST API
07.pallav
 
PPT
Basic of Multithreading in JAva
suraj pandey
 
PDF
Java Basic Oops Concept
atozknowledge .com
 
[KGC 2012]Boost.asio를 이용한 네트웍 프로그래밍
흥배 최
 
Multi threading
Ravi Kant Sahu
 
Enumeration in Java Explained | Java Tutorial | Edureka
Edureka!
 
Spring boot
Gyanendra Yadav
 
Java 17
Mutlu Okuducu
 
Spring Boot
Jaran Flaath
 
Spring boot jpa
Hamid Ghorbani
 
Spring - Part 2 - Autowiring, Annotations, Java based Configuration - slides
Hitesh-Java
 
20.3 Java encapsulation
Intro C# Book
 
Devoxx France 2023 - Les nouveautés de Java 19 et 20
Jean-Michel Doudoux
 
Java 8 Lambda and Streams
Venkata Naga Ravi
 
Lambda Expressions in Java | Java Lambda Tutorial | Java Certification Traini...
Edureka!
 
Spring Framework
nomykk
 
Java file
sonnetdp
 
Multithreading in java
Arafat Hossan
 
Java Spring Framework
Mehul Jariwala
 
Spring Boot and REST API
07.pallav
 
Basic of Multithreading in JAva
suraj pandey
 
Java Basic Oops Concept
atozknowledge .com
 
Ad

Viewers also liked (10)

PPTX
面對移動化App挑戰的架構設計
Clark
 
ODP
Threads and concurrency in Java 1.5
Peter Antman
 
PPTX
Introduction of Android Camera1
Booch Lin
 
PPTX
Java concurrency - Thread pools
maksym220889
 
PDF
JAVA GUI PART III
OXUS 20
 
PDF
Asynchronous API in Java8, how to use CompletableFuture
José Paumard
 
PDF
Node.js and Selenium Webdriver, a journey from the Java side
Mek Srunyu Stittri
 
PPTX
C++ ppt
Aneesh Gupta
 
PPTX
Reactive Programming in Java 8 with Rx-Java
Kasun Indrasiri
 
PDF
Concurrency: The Good, The Bad and The Ugly
legendofklang
 
面對移動化App挑戰的架構設計
Clark
 
Threads and concurrency in Java 1.5
Peter Antman
 
Introduction of Android Camera1
Booch Lin
 
Java concurrency - Thread pools
maksym220889
 
JAVA GUI PART III
OXUS 20
 
Asynchronous API in Java8, how to use CompletableFuture
José Paumard
 
Node.js and Selenium Webdriver, a journey from the Java side
Mek Srunyu Stittri
 
C++ ppt
Aneesh Gupta
 
Reactive Programming in Java 8 with Rx-Java
Kasun Indrasiri
 
Concurrency: The Good, The Bad and The Ugly
legendofklang
 
Ad

Similar to Concurrent Programming in Java (20)

PPTX
parallel-asynchronous-programming-java.pptx
2022ac05156
 
ODP
Java Concurrency
Carol McDonald
 
ODP
Java Concurrency, Memory Model, and Trends
Carol McDonald
 
PPTX
Concurrency Programming in Java - 07 - High-level Concurrency objects, Lock O...
Sachintha Gunasena
 
PDF
The Future of Futures - A Talk About Java 8 CompletableFutures
Haim Yadid
 
PDF
Concurrency-5.pdf
ssuser04005f
 
PDF
Java Tutorials - Concurrency
Christian Rubiales
 
PPTX
Fork and join framework
Minh Tran
 
PDF
Loom Virtual Threads in the JDK 19
José Paumard
 
PPTX
MULTITHREADING PROGRAMMING AND I/O THREAD
mohanrajm63
 
PDF
Flavors of Concurrency in Java
JavaDayUA
 
PDF
Java concurrency
Abhijit Gaikwad
 
PPTX
Concurrent talk
rahulrevo
 
PDF
Looming Marvelous - Virtual Threads in Java Javaland.pdf
jexp
 
PPTX
Back to the [Completable] Future
Sofiia Khomyn
 
PDF
Programming Sideways: Asynchronous Techniques for Android
Emanuele Di Saverio
 
PPT
cs4240-multithreading.ppt presentation on multi threading
ShrutiPanda12
 
PPTX
Multithreading and concurrency in android
Rakesh Jha
 
PPTX
Think Async in Java 8
Dmitry Alexandrov
 
PPTX
Concurrency in Java
Allan Huang
 
parallel-asynchronous-programming-java.pptx
2022ac05156
 
Java Concurrency
Carol McDonald
 
Java Concurrency, Memory Model, and Trends
Carol McDonald
 
Concurrency Programming in Java - 07 - High-level Concurrency objects, Lock O...
Sachintha Gunasena
 
The Future of Futures - A Talk About Java 8 CompletableFutures
Haim Yadid
 
Concurrency-5.pdf
ssuser04005f
 
Java Tutorials - Concurrency
Christian Rubiales
 
Fork and join framework
Minh Tran
 
Loom Virtual Threads in the JDK 19
José Paumard
 
MULTITHREADING PROGRAMMING AND I/O THREAD
mohanrajm63
 
Flavors of Concurrency in Java
JavaDayUA
 
Java concurrency
Abhijit Gaikwad
 
Concurrent talk
rahulrevo
 
Looming Marvelous - Virtual Threads in Java Javaland.pdf
jexp
 
Back to the [Completable] Future
Sofiia Khomyn
 
Programming Sideways: Asynchronous Techniques for Android
Emanuele Di Saverio
 
cs4240-multithreading.ppt presentation on multi threading
ShrutiPanda12
 
Multithreading and concurrency in android
Rakesh Jha
 
Think Async in Java 8
Dmitry Alexandrov
 
Concurrency in Java
Allan Huang
 

Recently uploaded (20)

PPTX
Generics jehfkhkshfhskjghkshhhhlshluhueheuhuhhlhkhk.pptx
yashpavasiya892
 
PPTX
AI ad its imp i military life read it ag
ShwetaBharti31
 
PPTX
How tech helps people in the modern era.
upadhyayaryan154
 
PPTX
Pengenalan perangkat Jaringan komputer pada teknik jaringan komputer dan tele...
Prayudha3
 
PPTX
Blue and Dark Blue Modern Technology Presentation.pptx
ap177979
 
PPTX
EthicalHack{aksdladlsfsamnookfmnakoasjd}.pptx
dagarabull
 
PDF
Data Protection & Resilience in Focus.pdf
AmyPoblete3
 
PPTX
The Latest Scam Shocking the USA in 2025.pptx
onlinescamreport4
 
PPTX
The Monk and the Sadhurr and the story of how
BeshoyGirgis2
 
PPTX
Artificial-Intelligence-in-Daily-Life (2).pptx
nidhigoswami335
 
PPTX
谢尔丹学院毕业证购买|Sheridan文凭不见了怎么办谢尔丹学院成绩单
mookxk3
 
PDF
KIPER4D situs Exclusive Game dari server Star Gaming Asia
hokimamad0
 
PDF
Generative AI Foundations: AI Skills for the Future of Work
hemal sharma
 
PDF
BGP Security Best Practices that Matter, presented at PHNOG 2025
APNIC
 
PPTX
nagasai stick diagrams in very large scale integratiom.pptx
manunagapaul
 
PPTX
Black Yellow Modern Minimalist Elegant Presentation.pptx
nothisispatrickduhh
 
PPT
Introduction to dns domain name syst.ppt
MUHAMMADKAVISHSHABAN
 
PDF
KIPER4D situs Exclusive Game dari server Star Gaming Asia
hokimamad0
 
PPTX
原版北不列颠哥伦比亚大学毕业证文凭UNBC成绩单2025年新版在线制作学位证书
e7nw4o4
 
PDF
Project English Paja Jara Alejandro.jpdf
AlejandroAlonsoPajaJ
 
Generics jehfkhkshfhskjghkshhhhlshluhueheuhuhhlhkhk.pptx
yashpavasiya892
 
AI ad its imp i military life read it ag
ShwetaBharti31
 
How tech helps people in the modern era.
upadhyayaryan154
 
Pengenalan perangkat Jaringan komputer pada teknik jaringan komputer dan tele...
Prayudha3
 
Blue and Dark Blue Modern Technology Presentation.pptx
ap177979
 
EthicalHack{aksdladlsfsamnookfmnakoasjd}.pptx
dagarabull
 
Data Protection & Resilience in Focus.pdf
AmyPoblete3
 
The Latest Scam Shocking the USA in 2025.pptx
onlinescamreport4
 
The Monk and the Sadhurr and the story of how
BeshoyGirgis2
 
Artificial-Intelligence-in-Daily-Life (2).pptx
nidhigoswami335
 
谢尔丹学院毕业证购买|Sheridan文凭不见了怎么办谢尔丹学院成绩单
mookxk3
 
KIPER4D situs Exclusive Game dari server Star Gaming Asia
hokimamad0
 
Generative AI Foundations: AI Skills for the Future of Work
hemal sharma
 
BGP Security Best Practices that Matter, presented at PHNOG 2025
APNIC
 
nagasai stick diagrams in very large scale integratiom.pptx
manunagapaul
 
Black Yellow Modern Minimalist Elegant Presentation.pptx
nothisispatrickduhh
 
Introduction to dns domain name syst.ppt
MUHAMMADKAVISHSHABAN
 
KIPER4D situs Exclusive Game dari server Star Gaming Asia
hokimamad0
 
原版北不列颠哥伦比亚大学毕业证文凭UNBC成绩单2025年新版在线制作学位证书
e7nw4o4
 
Project English Paja Jara Alejandro.jpdf
AlejandroAlonsoPajaJ
 

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

  • #7: 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.