Skip to content

javasync/idioms

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

28 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

idioms

Build Status Coverage Status

Different ways of dealing with asynchronicity, which is informally, to allow multiple things to happen "at the same time", i.e. concurrently.

You may find here 5 different approaches of using asynchronicity to count the total number of lines of given files (e.g. countLines(String...paths)), namely:

  1. Threads and blocking IO (avoid it)
  2. Tasks and blocking IO (avoid it)
  3. Asynchronous IO
    1. Callbacks
    2. CompletableFuture
    3. Reactive Streams

Motivation

Teaching Modelling and Design Patterns course at ISEL we should achieve Reactive Streams by the end of the semester. To that end, we start from the basis: Reactive + Streams. For familiarity, we start by:

  1. Streams and first with the Iterator, which is a well-known pattern for all students at 4th semester and later we move to java.util.stream.Stream.
  2. After that, we tackle Reactive Streams starting with asynchronous programming (this repo).

At the end, students are able to manage:

Multiplicity Access Call
T 1 item
Optional<T> 1 Internal
External
op.ifPresent(item -> …)
item = op.get()
Blocking
Iterator<T> * External item = iter.next() Blocking
Spliterator<T> * Internal iter.tryAdvance(item -> …)
iter.forEachRemaining(item -> …)
Blocking
CompletableFuture<T> 1 Internal cf.thenAccept(item -> …) Non-blocking
Publisher<T>
(e.g. RxJava, Reactor, Kotlin Flow)
* Internal pub.subscribe(item -> …) Non-blocking
Async Iterator
(e.g C# and .Net)
* External item = await iter.next()
for await(const item of iter) …
Non-blocking

(*) Notice that Spliterator is not only related with the Stream parallelism. For a quick explanation about its advantages in sequential processing you may read the answer of Brian Goetz here: Iterator versus Stream of Java 8.

CompletableFuture in a nutshell

Stream<T> CompletableFuture<T>
void forEach(Consumer<T>) CF<Void> thenAccept(Consumer<T>)
Stream<R> map(Function<T, R>) CF<R> thenApply(Function<T, R>)
Stream<R> flatMap(Function<T, Stream<R>>) CF<R> thenCompose(Function<T, CF<R>>)
Stream<T> peek(Consumer<T>) CF<T> whenComplete(BiConsumer<T,Throwable>)
Stream<R> zip(Stream<U>, BiFunction<T, U, R>) (*) CF<R> thenCombine(CF<U>, BiFunction<T, U, R>)

(*) does not exist in JDK.

Presentation

Releases

No releases published

Packages

No packages published

Languages