flavors of concurrency in java

59
Oleg Šelajev @shelajev ZeroTurnaround Flavors of Concurrency in Java

Upload: javadayua

Post on 06-Jan-2017

606 views

Category:

Software


4 download

TRANSCRIPT

Page 1: Flavors of Concurrency in Java

Oleg Šelajev @shelajev

ZeroTurnaround

Flavors of Concurrency in Java

Page 2: Flavors of Concurrency in Java

whoami

@shelajev

Page 3: Flavors of Concurrency in Java
Page 4: Flavors of Concurrency in Java

WHY DO WE CARE?

Page 5: Flavors of Concurrency in Java

WHY DO WE CARE?

https://twitter.com/reubenbond/status/662061791497744384

Page 6: Flavors of Concurrency in Java

DEVS CHOOSING TECHNOLOGY

Page 7: Flavors of Concurrency in Java

CONCURRENCY | PARALLELISM

http://joearms.github.io/2013/04/05/concurrent-and-parallel-programming.html

Page 8: Flavors of Concurrency in Java

CONCURRENCY

Shared resources Multiple consumers & producers

Out of order events Locks & Deadlocks

Page 9: Flavors of Concurrency in Java

THEORY

Page 10: Flavors of Concurrency in Java

PRACTICE

Page 11: Flavors of Concurrency in Java

THREADS

ORGANIZED THREADS

FORK-JOIN FRAMEWORK

COMPLETABLE FUTURES ACTORS FIBERS

SOFTWARE TRANSACTIONAL MEMORY

Page 12: Flavors of Concurrency in Java

HOW TO MANAGE CONCURRENCY?

http://zeroturnaround.com/rebellabs/flavors-of-concurrency-in-java-threads-executors-forkjoin-and-actors/

Page 13: Flavors of Concurrency in Java

PROBLEM ORIENTED PROGRAMMING

Page 14: Flavors of Concurrency in Java

PROBLEMprivate static String getFirstResult(String question, List<String> engines) { // HERE BE DRAGONS, PARALLEL DRAGONS return null;}

Page 15: Flavors of Concurrency in Java
Page 16: Flavors of Concurrency in Java

WHY THREADS

Model Hardware Processes Threads

Page 17: Flavors of Concurrency in Java

THREADSprivate static String getFirstResult(String question, List<String> engines) { AtomicReference<String> result = new AtomicReference<>(); for(String base: engines) { String url = base + question; new Thread(() -> { result.compareAndSet(null, WS.url(url).get()); }).start(); } while(result.get() == null); // wait for the result to appear return result.get();}

Page 18: Flavors of Concurrency in Java

THREAD SAFETYA piece of code is thread-safe if it only manipulates shared data structures in

a manner that guarantees safe execution by multiple threads at the

same time.https://en.wikipedia.org/wiki/Thread_safety

Page 19: Flavors of Concurrency in Java

COMMUNICATION

Objects & Fields Atomics* Queues

Database

Page 20: Flavors of Concurrency in Java

COMMUNICATION

Page 21: Flavors of Concurrency in Java

COMMUNICATION

Page 22: Flavors of Concurrency in Java

COMMUNICATION

The Java Language Specification

17.4. Memory Model

Page 23: Flavors of Concurrency in Java

TAKEAWAY: THREADS

Threads take resources Require manual management

Easy Not so simple

Page 24: Flavors of Concurrency in Java
Page 25: Flavors of Concurrency in Java

EXECUTORS

public interface Executor { void execute(Runnable command);}

public interface ExecutorCompletionService<V> { public Future<V> submit(Callable<V> task); public Future<V> take();}

Page 26: Flavors of Concurrency in Java

EXECUTORSprivate static String getFirstResultExecutors(String question, List<String> engines) { ExecutorCompletionService<String> service = new ExecutorCompletionService<String>(Executors.newFixedThreadPool(4)); for(String base: engines) { String url = base + question; service.submit(() -> { return WS.url(url).get(); }); } try { return service.take().get(); } catch(InterruptedException | ExecutionException e) { return null; }}

Page 27: Flavors of Concurrency in Java

EXECUTORSprivate static String getFirstResultExecutors(String question, List<String> engines) { ExecutorCompletionService<String> service = new ExecutorCompletionService<String>(Executors.newFixedThreadPool(4)); for(String base: engines) { String url = base + question; service.submit(() -> { return WS.url(url).get(); }); } try { return service.take().get(); } catch(InterruptedException | ExecutionException e) { return null; }}

Page 28: Flavors of Concurrency in Java

EXECUTORSprivate static String getFirstResultExecutors(String question, List<String> engines) { ExecutorCompletionService<String> service = new ExecutorCompletionService<String>(Executors.newFixedThreadPool(4)); for(String base: engines) { String url = base + question; service.submit(() -> { return WS.url(url).get(); }); } try { return service.take().get(); } catch(InterruptedException | ExecutionException e) { return null; }}

Page 29: Flavors of Concurrency in Java

EXECUTORSprivate static String getFirstResultExecutors(String question, List<String> engines) { ExecutorCompletionService<String> service = new ExecutorCompletionService<String>(Executors.newFixedThreadPool(4)); for(String base: engines) { String url = base + question; service.submit(() -> { return WS.url(url).get(); }); } try { return service.take().get(); } catch(InterruptedException | ExecutionException e) { return null; }}

Page 30: Flavors of Concurrency in Java

CONCERNS: EXECUTORS

Queue size Overflow strategy Cancellation strategy

Page 31: Flavors of Concurrency in Java

TAKEAWAY: EXECUTORS

Simple configuration Bounded overhead

Pushing complexity deeper

Page 32: Flavors of Concurrency in Java

http://i.ytimg.com/vi/6_W_xLWtNa0/maxresdefault.jpg

Page 33: Flavors of Concurrency in Java

FORK JOIN FRAMEWORK

Recursive tasks General parallel tasks

Work stealing

Page 35: Flavors of Concurrency in Java

FORK JOIN POOLprivate static String getFirstResult(String question, List<String> engines) { // get element as soon as it is available Optional<String> result = engines.stream() .parallel().map((base) -> { String url = base + question; return WS.url(url).get(); }).findAny(); return result.get();}

Page 36: Flavors of Concurrency in Java

TAKEAWAY: FORK JOIN POOL

Efficient Preconfigured

Easy to get right Easy to get wrong

Page 37: Flavors of Concurrency in Java
Page 38: Flavors of Concurrency in Java

COMPLETABLE FUTURESprivate static String getFirstResultCompletableFuture(String question, List<String> engines) { CompletableFuture result = CompletableFuture.anyOf(engines.stream().map( (base) -> { return CompletableFuture.supplyAsync(() -> { String url = base + question; return WS.url(url).get(); }); } ).collect(Collectors.toList()).toArray(new CompletableFuture[0])); try { return (String) result.get(); } catch (InterruptedException | ExecutionException e) { return null; }}

Page 39: Flavors of Concurrency in Java

COMPLETABLE FUTURESprivate static String getFirstResultCompletableFuture(String question, List<String> engines) { CompletableFuture result = CompletableFuture.anyOf(engines.stream().map( (base) -> { return CompletableFuture.supplyAsync(() -> { String url = base + question; return WS.url(url).get(); }); } ).collect(Collectors.toList()).toArray(new CompletableFuture[0])); try { return (String) result.get(); } catch (InterruptedException | ExecutionException e) { return null; }}

Page 40: Flavors of Concurrency in Java

Using types

java.util.concurrent.CompletableFuture

thenApply(Function / Consumer / etc)

thenApplyAsync(Function / etc)

Page 41: Flavors of Concurrency in Java

Completable Future

https://vimeo.com/131394616

Page 42: Flavors of Concurrency in Java
Page 43: Flavors of Concurrency in Java

ACTORSstatic class Message { String url; Message(String url) {this.url = url;}}

static class Result { String html; Result(String html) {this.html = html;}}

Page 44: Flavors of Concurrency in Java

ACTORSstatic class UrlFetcher extends UntypedActor { @Override public void onReceive(Object message) throws Exception { if (message instanceof Message) { Message work = (Message) message; String result = WS.url(work.url).get(); getSender().tell(new Result(result), getSelf()); } else { unhandled(message); } }}

Page 45: Flavors of Concurrency in Java

ACTORSpublic static interface Squarer {

//fire-forget void squareDontCare(int i); //non-blocking send-request-reply Future<Integer> square(int i); //blocking send-request-reply Option<Integer> squareNowPlease(int i); //blocking send-request-reply int squareNow(int i);}

Page 46: Flavors of Concurrency in Java

TAKEAWAY: ACTORS

OOP is about messages Multiplexing like a boss

Supervision & Fault tolerance

Page 47: Flavors of Concurrency in Java

http://static1.squarespace.com/static/50aa813ce4b0726ad3f3fdb0/51e1e393e4b0180cf3bcbb46/51e1e39ae4b0fa94cee721f9/1373758363472/forest-by-marshmallow-laser-feast-the-tree-mag-30.jpg

Page 48: Flavors of Concurrency in Java

FIBERS

Lightweight threads

Page 49: Flavors of Concurrency in Java
Page 50: Flavors of Concurrency in Java

TAKEAWAY: FIBERS

Continuations Progress all over the place

Bytecode modification Highly scalable

Page 51: Flavors of Concurrency in Java
Page 52: Flavors of Concurrency in Java

TRANSACTIONAL MEMORY

Page 53: Flavors of Concurrency in Java

TAKEAWAY: TX MEMORY

Optimistic writes Retry / Fail

ACID

Page 54: Flavors of Concurrency in Java

THREADS

ORGANIZED THREADS

FORK-JOIN FRAMEWORK

COMPLETABLE FUTURES ACTORS FIBERS

SOFTWARE TRANSACTIONAL MEMORY

Page 55: Flavors of Concurrency in Java

CONCLUSION

Page 56: Flavors of Concurrency in Java

Seven Concurrency Models in Seven

Weeks: When Threads Unravel

by Paul Butcherhttps://pragprog.com/book/pb7con/seven-concurrency-models-in-seven-weeks

Page 57: Flavors of Concurrency in Java

http://www.amazon.com/The-Multiprocessor-Programming-Revised-Reprint/dp/0123973376

The Art of Multiprocessor Programming

by Maurice Herlihy, Nir Shavit

Page 58: Flavors of Concurrency in Java

http://0t.ee/javadaykiev

Page 59: Flavors of Concurrency in Java

[email protected] @shelajev

Contact me