nicety of java 8 multithreading

16
1 Nicety of java 8 multithreading for advanced Maksym Voroniy Software Architect of GlobalLogic

Upload: globallogic-ukraine

Post on 22-Jan-2018

1.646 views

Category:

Software


0 download

TRANSCRIPT

Page 1: Nicety of Java 8 Multithreading

1

Nicety of java 8 multithreading for advanced

Maksym VoroniySoftware Architect of GlobalLogic

Page 2: Nicety of Java 8 Multithreading

2

Common points01

Page 3: Nicety of Java 8 Multithreading

3

History

Text

The Dream Time sharing

Stone Age Intel 80386

Multiple data

multiple handlers

Multiple processo

rs

Multiple data

single handler

Hyper threading

IBM 360

CUDA

Multicore

Today

Page 4: Nicety of Java 8 Multithreading

4

Point #1

Maurice Herlihy & Nir Shavit “The Art of Multiprocessor Programming”

Page 5: Nicety of Java 8 Multithreading

5

Atomicity vs Consistence

static int a = 5;

a *= 3;

int b = 22;

b += a;

mov EAX, 5

mov ds:[a], EAX

mul 3

mov ds:[a], EAX

mov EBX, 22

add EBX, EAX;vs add EBX,ds:[a]

atomicity

consistence

Page 6: Nicety of Java 8 Multithreading

6

Java 8 FAA vs CAS02

Page 7: Nicety of Java 8 Multithreading

7

Nicety #1 - Java 8 Atomics

http://ashkrit.blogspot.com/2014/02/atomicinteger-java-7-vs-java-8.html

fetch-and-add vs compare-and-swap (CAS)

JDK 8 - AtomicIntegerpublic final int getAndIncrement() {

return unsafe.getAndAddInt(

this, valueOffset, 1);

}

JDK7 - AtomicIntegerpublic final int getAndIncrement() {

for (;;) {

int current = get();

int next = current + 1;

if (compareAndSet(current, next))

return current;

}

}

Page 8: Nicety of Java 8 Multithreading

8

Why Atomic important?

Text

ConcurrentHashMap<>

Collections.synchronizedMap(new HashMap<>())

• ConcurrentLinkedDeque/Queue

• ConcurrentSkipListSet/Map

• ConcurrentHashMap

• wait-free, if every concurrent operation is guaranteed to be

finished in a finite number of steps

• lock-free, if some concurrent operations are guaranteed to

be finished in a finite number of steps.

DARE

develop concurrent hash-map

TODAY tomorrow

Page 9: Nicety of Java 8 Multithreading

9

ConcurrentHashMap

StampedLock goes to stage

Text

Simple cache implementation (value by key):

(T key, Map<T, V> map) -> {

return map.get(i);

}synchronizedMap(new HashMap<>())

(T key, Map<T, V> map) -> {

synchronized (map){

return map.get(i);

}

}

HashMap + ReadWriteLock

(T key, Map<T, V> map) -> {

Lock l = rwLock.readLock();

l.lock();

try {

return map.get(i);

} finally {

l.unlock();

}}

Page 10: Nicety of Java 8 Multithreading

10

StampedLock goes to stage (II)

Text

HashMap + StampedLock

(T key, Map<T, V> map) -> {

long l = stampedLock.readLock();

try {

return map.get(i);

} finally {

stampedLock.unlockRead(l);

}}

HashMap + StampedLock+Optimistic

(T key, Map<T, V> map) -> {

long stamp = optimisticLock.tryOptimisticRead();

Integer r = map.get(i);

if (!optimisticLock.validate(stamp)) {

stamp = optimisticLock.readLock();

try {

return map.get(i);

} finally {

optimisticLock.unlockRead(stamp);

}

}

return r;

}

200`000 op for 10

Threads

Nanoseconds

ConcurrentHashMap 72645.057

Optimistic 359819.982

StampedLock 1303853.525

ReadWriteLock 1326939.766

Locked 1922399.053

Page 11: Nicety of Java 8 Multithreading

11

Java 8 Parallelism03

Page 12: Nicety of Java 8 Multithreading

12

.parallelStream()

Text

//from Oracle tutorial:

double average = roster

.parallelStream()

.filter(p -> p.getGender() == Person.Sex.MALE)

.mapToInt(Person::getAge)

.average()

.getAsDouble()

• Java runtime partitions the stream into

multiple substreams. Aggregate operations

iterate over and process these substreams in

parallel and then combine the results

static ExecutorService newWorkStealingPool()

static ExecutorService newFixedThreadPool(int nThreads)

static ScheduledExecutorService newScheduledThreadPool(int corePoolSize)

static ExecutorService newCachedThreadPool(ThreadFactory threadFactory)

• Work Stealing (An idle thread steals work from a thread having tasks queued up more than it

can process currently)

• Ability to recursively decompose the tasks and collect the results. (Apparently, this requirement

must have popped up along with the conception of the notion of parallel processing... but lacked

a solid implementation framework in Java till Java 7)

ForkJoinPool

Page 13: Nicety of Java 8 Multithreading

13

The trap!

List<SomeClass> list = // A list of objects

list.parallelStream()

.map(this::veryLongProcessing)

.collect(toList());

part

itio

n Stream-1

Stream-2

Stream-3

Core -1 Core -2

ForkJoinPool forkJoinPool = new ForkJoinPool(2);

forkJoinPool.submit(() ->

list.parallel()

.map(this::veryLongProcessing)

.collect(toList())

).get();

"Arranges to asynchronously execute this task in the pool the

current task is running in, if applicable, or using theForkJoinPool.commonPool() if not in

ForkJoinPool()"

Page 14: Nicety of Java 8 Multithreading

14

The Future

Text

Time sharing

Stone Age Intel 80386

Hyper threading

IBM 360

CUDA

Multicore

HTMSTM

Page 15: Nicety of Java 8 Multithreading

15

Future direction

• How Databases works (SQL& NoSQL)

• Quantum computing

• Advanced data structures (R-Tree, B-Tree, Trie, Skip-lists, Heaps…)

http://goo.gl/forms/9LauaeJBlO

N

Page 16: Nicety of Java 8 Multithreading

16

Thank you!

Any Questions?