KEMBAR78
Nicety of Java 8 Multithreading | PPTX
1
Nicety of java 8 multithreading for advanced
Maksym Voroniy
Software Architect of GlobalLogic
2
Common points01
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
4
Point #1
Maurice Herlihy & Nir Shavit “The Art of Multiprocessor Programming”
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
6
Java 8 FAA vs CAS02
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 - AtomicInteger
public final int getAndIncrement() {
return unsafe.getAndAddInt(
this, valueOffset, 1);
}
JDK7 - AtomicInteger
public final int getAndIncrement() {
for (;;) {
int current = get();
int next = current + 1;
if (compareAndSet(current, next))
return current;
}
}
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
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();
}}
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
11
Java 8 Parallelism03
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
13
The trap!
List<SomeClass> list = // A list of objects
list.parallelStream()
.map(this::veryLongProcessing)
.collect(toList());
partition
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 the
ForkJoinPool.commonPool() if not in
ForkJoinPool()"
14
The Future
Text
Time sharing
Stone Age Intel 80386
Hyper threading
IBM 360
CUDA
Multicore
HTMSTM
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
16
Thank you!
Any Questions?

Nicety of Java 8 Multithreading

  • 1.
    1 Nicety of java8 multithreading for advanced Maksym Voroniy Software Architect of GlobalLogic
  • 2.
  • 3.
    3 History Text The Dream Timesharing Stone Age Intel 80386 Multiple data multiple handlers Multiple processo rs Multiple data single handler Hyper threading IBM 360 CUDA Multicore Today
  • 4.
    4 Point #1 Maurice Herlihy& Nir Shavit “The Art of Multiprocessor Programming”
  • 5.
    5 Atomicity vs Consistence staticint 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
  • 6.
    6 Java 8 FAAvs CAS02
  • 7.
    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 - AtomicInteger public final int getAndIncrement() { return unsafe.getAndAddInt( this, valueOffset, 1); } JDK7 - AtomicInteger public final int getAndIncrement() { for (;;) { int current = get(); int next = current + 1; if (compareAndSet(current, next)) return current; } }
  • 8.
    8 Why Atomic important? Text ConcurrentHashMap<> Collections.synchronizedMap(newHashMap<>()) • 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
  • 9.
    9 ConcurrentHashMap StampedLock goes tostage 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(); }}
  • 10.
    10 StampedLock goes tostage (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
  • 11.
  • 12.
    12 .parallelStream() Text //from Oracle tutorial: doubleaverage = 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
  • 13.
    13 The trap! List<SomeClass> list= // A list of objects list.parallelStream() .map(this::veryLongProcessing) .collect(toList()); partition 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 the ForkJoinPool.commonPool() if not in ForkJoinPool()"
  • 14.
    14 The Future Text Time sharing StoneAge Intel 80386 Hyper threading IBM 360 CUDA Multicore HTMSTM
  • 15.
    15 Future direction • HowDatabases works (SQL& NoSQL) • Quantum computing • Advanced data structures (R-Tree, B-Tree, Trie, Skip-lists, Heaps…) http://goo.gl/forms/9LauaeJBlO N
  • 16.