What's new in java.util.concurrent

60
Обзор нововведений в j.u.c (JSR 166e) Дмитрий Чуйко [email protected]

description

 

Transcript of What's new in java.util.concurrent

Page 1: What's new in java.util.concurrent

Обзор нововведений в j.u.c(JSR 166e)

Дмитрий Чуйко[email protected]

Page 2: What's new in java.util.concurrent

Outline

Введение

Что нового

Атомарные переменные

Locks

Accumulators

Collections

Slide 2/60. Copyright c○ 2013, Oracle and/or its affiliates. All rights reserved.

Page 3: What's new in java.util.concurrent

The following is intended to outline our general product direction. Itis intended for information purposes only, and may not beincorporated into any contract. It is not a commitment to deliver anymaterial, code, or functionality, and should not be relied upon inmaking purchasing decisions. The development, release, and timingof any features or functionality described for Oracle’s productsremains at the sole discretion of Oracle.

Slide 3/60. Copyright c○ 2013, Oracle and/or its affiliates. All rights reserved.

Page 4: What's new in java.util.concurrent

Введение

Slide 4/60. Copyright c○ 2013, Oracle and/or its affiliates. All rights reserved.

Page 5: What's new in java.util.concurrent

Введение: Ресурсы

Concurrency JSR-166 Interest Sitehttp://g.oswego.edu/dl/concurrency-interest/JDK 8http://jdk8.java.net/Project Lambdahttp://openjdk.java.net/projects/lambda/JMHhttp://openjdk.java.net/projects/code-tools/jmh/

Slide 5/60. Copyright c○ 2013, Oracle and/or its affiliates. All rights reserved.

Page 6: What's new in java.util.concurrent

Введение: Мир, в котором мы живём

Всем нужны масштабируемость, надёжность,производительностьThe Free Lunch Is Over Herb SutterМногопоточность может возникать из-за условий задачиМногопроцессорность/многоядерность везде

Slide 6/60. Copyright c○ 2013, Oracle and/or its affiliates. All rights reserved.

Page 7: What's new in java.util.concurrent

История: Цели

Параллелизация за кулисамиЗагрузка процессора полезной работойХорошие алгоритмы

Slide 7/60. Copyright c○ 2013, Oracle and/or its affiliates. All rights reserved.

Page 8: What's new in java.util.concurrent

История: Java Concurrency Timeline

JDK 1.0 !  JMM

!  synchronizied !  Thread

1996 1997 2004

JDK 1.2 ! Collections

JDK 5 !  JMM

!  java.util.concurrent

JSRs !  JSR 133

!  JSR 166

Doug Lea ! Concurrency

package

1998 2006

JDK 6 ! Navigable!

JSRs

!  JSR 166x

2011

JDK 7 !  FJP,!

JSRs

!  JSR 166y

JDK 8

!  java.util.concurrent

JSRs

!  JSR 166e

Slide 8/60. Copyright c○ 2013, Oracle and/or its affiliates. All rights reserved.

Page 9: What's new in java.util.concurrent

История: Алгоритмы с координацией

Блокирующиеся (blocking)Неблокирующиеся (nonblocking) При остановке однойнити у других есть шанс закончить работу

Без препятствий (obstruction-free) Любая нить в изоляцииможет закончить работуСвободные от блокировок (lock-free) На каждом шагепродвигается какая-либо из нитейБез ожиданий (wait-free) Каждая нить продвигается

Алгоритмы, основанные на CAS, могут быть nonblockinglock-free

Slide 9/60. Copyright c○ 2013, Oracle and/or its affiliates. All rights reserved.

Page 10: What's new in java.util.concurrent

История: Состав

Java Concurrency Utilities

ExecutorsSynchronizers CollectionsAtomics Locks Nano time

Slide 10/60. Copyright c○ 2013, Oracle and/or its affiliates. All rights reserved.

Page 11: What's new in java.util.concurrent

История: Атомарные переменные

Обёртки примитивов, ссылок, управление полямиCompare-And-SetАтомарная арифметика

Slide 11/60. Copyright c○ 2013, Oracle and/or its affiliates. All rights reserved.

Page 12: What's new in java.util.concurrent

История: Синхронизация

Semaphores, mutexes, barriers, latches, exchangersУдобство синхронизации

LocksПроизводительностьМодель памяти. Эффект эквивалентен synchronizedГибкость

Slide 12/60. Copyright c○ 2013, Oracle and/or its affiliates. All rights reserved.

Page 13: What's new in java.util.concurrent

История: Concurrent Collections

(Blocking)(De)Queue, Map, ListПараллельный доступВысокая производительность

Slide 13/60. Copyright c○ 2013, Oracle and/or its affiliates. All rights reserved.

Page 14: What's new in java.util.concurrent

История: Task Scheduling Framework

Executor’ыВыполнение асинхронных задачПолитики выполнения

Slide 14/60. Copyright c○ 2013, Oracle and/or its affiliates. All rights reserved.

Page 15: What's new in java.util.concurrent

Что нового

Slide 15/60. Copyright c○ 2013, Oracle and/or its affiliates. All rights reserved.

Page 16: What's new in java.util.concurrent

Что нового: Тот же фундамент

RuntimeLockSupportUnsafe

JVMIntrinsics

OSpthreads mutex

HardwareCAS

Slide 16/60. Copyright c○ 2013, Oracle and/or its affiliates. All rights reserved.

Page 17: What's new in java.util.concurrent

Что нового: JC Utilities

ExecutorsCompletableFuture CountedCompleter ForkJoinPool

Collections Accumulators CombinedConcurrentHashMap LongAccumulator LongAdderTable

DoubleAccumulatorLongAdderDoubleAdder

Locks AtomicsStampedLock AtomicDoubleArray

AtomicDouble

Slide 17/60. Copyright c○ 2013, Oracle and/or its affiliates. All rights reserved.

Page 18: What's new in java.util.concurrent

Низкоуровневые API: Мотивация

JMM абстрактна, железо конкретноЕсть полезные трюкиНе используйте низкоуровневые API напрямую

Slide 18/60. Copyright c○ 2013, Oracle and/or its affiliates. All rights reserved.

Page 19: What's new in java.util.concurrent

Низкоуровневые API: Unsafe

Не часть языкаОбход JMMsun.misc

Unsafe API в HotspotАккуратныйАбстрактныйДостаточный

Не используйте Unsafe напрямую, это unsafe

Slide 19/60. Copyright c○ 2013, Oracle and/or its affiliates. All rights reserved.

Page 20: What's new in java.util.concurrent

Низкоуровневые API: Unsafe

Новая механикаstoreFence()loadFence()fullFence()Использование в реализации Locks

Slide 20/60. Copyright c○ 2013, Oracle and/or its affiliates. All rights reserved.

Page 21: What's new in java.util.concurrent

Атомарные переменные

Slide 21/60. Copyright c○ 2013, Oracle and/or its affiliates. All rights reserved.

Page 22: What's new in java.util.concurrent

Атомарные переменные: Чего не хватает

Для каких примитивных типов нет Atomic-типов?В каких числах чаще всего считаем?Возникают массивы атомарных данных

Slide 22/60. Copyright c○ 2013, Oracle and/or its affiliates. All rights reserved.

Page 23: What's new in java.util.concurrent

Атомарные переменные: AtomicDouble

Брат-близнец AtomicLongNumber, SerializablecompareAndSet(double expect, double update)addAndGet(double delta)Равенство битов значений

doubleToRawLongBits()

Slide 23/60. Copyright c○ 2013, Oracle and/or its affiliates. All rights reserved.

Page 24: What's new in java.util.concurrent

Атомарные переменные: AtomicDoubleArray

Брат-близнец AtomicLongArraySerializablecompareAndSet(int i, double expect, double update)addAndGet(int i, double delta)Равенство битов значений

doubleToRawLongBits()

Slide 24/60. Copyright c○ 2013, Oracle and/or its affiliates. All rights reserved.

Page 25: What's new in java.util.concurrent

Атомарные переменные: Performance

Приводимые результатыIntel R○ Xeon R○ E5-2680 (2x8x2)LinuxJDK 7OpenJDK JMH 1.0

Slide 25/60. Copyright c○ 2013, Oracle and/or its affiliates. All rights reserved.

Page 26: What's new in java.util.concurrent

Атомарные переменные: AtomicDoubleArray

Тест производительностиНе слишком маленький массивЧитатели делают get()Писатели делают compareAndSet()Произвольный равномерный доступ

Slide 26/60. Copyright c○ 2013, Oracle and/or its affiliates. All rights reserved.

Page 27: What's new in java.util.concurrent

Атомарные переменные: AtomicDoubleArray

0

200

400

25 50 75% of writers

Rea

d th

roug

hput

, ops

/use

c

Benchmark

AtomicDouble[]

AtomicDoubleArray

T=32

0

100

200

300

25 50 75 100% of writers

Writ

e th

roug

hput

, ops

/use

c

Benchmark

AtomicDouble[]

AtomicDoubleArray

T=32

Slide 27/60. Copyright c○ 2013, Oracle and/or its affiliates. All rights reserved.

Page 28: What's new in java.util.concurrent

Locks

Slide 28/60. Copyright c○ 2013, Oracle and/or its affiliates. All rights reserved.

Page 29: What's new in java.util.concurrent

Locks: ReentrantReadWriteLock

Lock, блокировка на чтение, на записьПовторная входимость (reentrancy)Пробная блокировка, таймауты, прерываемостьConditionsFair/unfairSerializable. . .Memory effects

Slide 29/60. Copyright c○ 2013, Oracle and/or its affiliates. All rights reserved.

Page 30: What's new in java.util.concurrent

Locks: Чего бы хотелось

Блокировка на чтение, на записьОптимистичные блокировкиUpgrade/downgradeПростота использованияИ чтобы быстро работало

Slide 30/60. Copyright c○ 2013, Oracle and/or its affiliates. All rights reserved.

Page 31: What's new in java.util.concurrent

Locks: ReentrantReadWriteLock

readLock() на чтение, writeLock() на записьПопробуйте написать оптимистичную блокировку,гарантировать memory effectsDowngrade: захват RL под WLПостоянно работает с ThreadLocal

Slide 31/60. Copyright c○ 2013, Oracle and/or its affiliates. All rights reserved.

Page 32: What's new in java.util.concurrent

Locks: StampedLock

Пример из javadoc

Slide 32/60. Copyright c○ 2013, Oracle and/or its affiliates. All rights reserved.

Page 33: What's new in java.util.concurrent

Locks: StampedLock

Listing 1: Pointclass Point {

private double x, y;private final StampedLock sl = new StampedLock ();...

Slide 33/60. Copyright c○ 2013, Oracle and/or its affiliates. All rights reserved.

Page 34: What's new in java.util.concurrent

Locks: StampedLock

Listing 2: Optimistic Readdouble distanceFromOrigin () { // A read -only method

long stamp = sl.tryOptimisticRead ();double currentX = x, currentY = y;if (!sl.validate(stamp )) {

stamp = sl.readLock ();try {

currentX = x;currentY = y;

} finally {sl.unlockRead(stamp );

}}return Math.sqrt(currentX * currentX + currentY * currentY );

}

Slide 34/60. Copyright c○ 2013, Oracle and/or its affiliates. All rights reserved.

Page 35: What's new in java.util.concurrent

Locks: StampedLock. Upgradevoid moveIfAtOrigin(double newX , double newY) { // upgrade

// Could instead start with optimistic , not read modelong stamp = sl.readLock ();try {

while (x == 0.0 && y == 0.0) {long ws = sl.tryConvertToWriteLock(stamp);if (ws != 0L) {

stamp = ws;x = newX;y = newY;break;

}else {

sl.unlockRead(stamp );stamp = sl.writeLock ();

}}

} finally {sl.unlock(stamp );

}}

Slide 35/60. Copyright c○ 2013, Oracle and/or its affiliates. All rights reserved.

Page 36: What's new in java.util.concurrent

Locks: StampedLock

Оптимистичные блокировкиЕсли проверки неудачные, можно захватить блокировку

Обычно удачныеВыигрыш

Мало записей => в разыНет записей => на порядкиВне блокировки, проверенное состояние может статьнеактуальным

Slide 36/60. Copyright c○ 2013, Oracle and/or its affiliates. All rights reserved.

Page 37: What's new in java.util.concurrent

Locks: StampedLock

Повышение уровня блокировкиМожет не быть выигрыша, если не ограничивать записьВалидное состояние

В обычном варианте может быть в разы быстрее RRWLНе гарантировано!При этом потребляет меньше ресурсовМожно передавать метку

Slide 37/60. Copyright c○ 2013, Oracle and/or its affiliates. All rights reserved.

Page 38: What's new in java.util.concurrent

Accumulators

Slide 38/60. Copyright c○ 2013, Oracle and/or its affiliates. All rights reserved.

Page 39: What's new in java.util.concurrent

Accumulators: Задача

Инкрементируем счётчик в разных нитяхНити подбирают работу и имеют доступ к общему контексту

Slide 39/60. Copyright c○ 2013, Oracle and/or its affiliates. All rights reserved.

Page 40: What's new in java.util.concurrent

Accumulators: Простое решение

AtomicLong atomicLong = new AtomicLong (0L); // context...atomicLong.getAndIncrement (); // N threads...long sharedSum = atomicLong.get ();

Slide 40/60. Copyright c○ 2013, Oracle and/or its affiliates. All rights reserved.

Page 41: What's new in java.util.concurrent

Accumulators: AtomicLong

SharingSpin loop + CAS, много

Slide 41/60. Copyright c○ 2013, Oracle and/or its affiliates. All rights reserved.

Page 42: What's new in java.util.concurrent

Accumulators: LongAdder

Защита от коллизий за счёт структуры и алгоритмаПохож на комбинацию unshared padded AtomicLong’овПростой APINumber

Slide 42/60. Copyright c○ 2013, Oracle and/or its affiliates. All rights reserved.

Page 43: What's new in java.util.concurrent

Accumulators: Решение

LongAdder longAdder = new LongAdder (); // context...longAdder.increment (); // N threads...long sharedSum = longAdder.sum();

Slide 43/60. Copyright c○ 2013, Oracle and/or its affiliates. All rights reserved.

Page 44: What's new in java.util.concurrent

Accumulators: DoubleAdder

Аналогичен LongAdder, только для doubleБольшая часть логики одинаковая, базовый класс Striped64

Slide 44/60. Copyright c○ 2013, Oracle and/or its affiliates. All rights reserved.

Page 45: What's new in java.util.concurrent

Accumulators: Atomic Update

// AtomicLong , JDK 7public final long addAndGet(long delta) {

for (;;) {long current = get();long next = current + delta;if (compareAndSet(current , next))

return next;}

}

Slide 45/60. Copyright c○ 2013, Oracle and/or its affiliates. All rights reserved.

Page 46: What's new in java.util.concurrent

Accumulators: Произвольные коммутативныеоперации

Заменяем ’+’ функциейStriped64, NumberLongAccumulator аналогичен LongAdder

new LongAccumulator(Long::sum, 0L)DoubleAccumulator аналогичен DoubleAdder

new DoubleAccumulator(Double::sum, 0.0D)

Slide 46/60. Copyright c○ 2013, Oracle and/or its affiliates. All rights reserved.

Page 47: What's new in java.util.concurrent

Accumulators: LongMaxUpdater

new LongAccumulator(Long::max, Long.MIN_VALUE)Тест производительности

accumulate(nextLocalLongMax)

Slide 47/60. Copyright c○ 2013, Oracle and/or its affiliates. All rights reserved.

Page 48: What's new in java.util.concurrent

Accumulators: LongMaxUpdater

10

100

1000

0 20 40 60Threads

Thr

ough

put,

ops/

usec

(lo

g sc

ale)

Benchmark Unshared CAS LongMaxUpdater AtomicLong long+Lock

Slide 48/60. Copyright c○ 2013, Oracle and/or its affiliates. All rights reserved.

Page 49: What's new in java.util.concurrent

Accumulators: Подводные камни

Local, ThreadLocal – эффективнее, если можно применитьget(), reset() под нагрузкой просаживаютпроизводительность

Обход всех ячеекГраницы эффекта

Система до насыщенияИтерации менее 1 мкс

Slide 49/60. Copyright c○ 2013, Oracle and/or its affiliates. All rights reserved.

Page 50: What's new in java.util.concurrent

Collections

Slide 50/60. Copyright c○ 2013, Oracle and/or its affiliates. All rights reserved.

Page 51: What's new in java.util.concurrent

ConcurrentHashMap: CHMv7

Lock stripingConcurrency levelСегмент - ReentrantLock

get() без блокировкиЗащита от DoS

Другой хэш для String

Slide 51/60. Copyright c○ 2013, Oracle and/or its affiliates. All rights reserved.

Page 52: What's new in java.util.concurrent

ConcurrentHashMap: CHMv8

Lock stripingConcurrency level не используется, подстройка в процессе работыNode: synchronized или AbstractQueuedSynchronizer

get() без блокировки или под блокировкой на чтениеЗащита от DoS

Сбалансированное дерево для Comparable - performance

Slide 52/60. Copyright c○ 2013, Oracle and/or its affiliates. All rights reserved.

Page 53: What's new in java.util.concurrent

ConcurrentHashMap: CHMv8 vs CHMv7

Тест производительностиInteger-like ключиconcurrencyLevel == 32Размер порядка L3Нормальное распределениеput()

Slide 53/60. Copyright c○ 2013, Oracle and/or its affiliates. All rights reserved.

Page 54: What's new in java.util.concurrent

ConcurrentHashMap: Масштабируемость

1

10

0 20 40 60Threads

Thr

ough

put,

ops/

usec

(lo

g sc

ale)

Benchmark CHMv8 CHMv7 HashMap+ReentrantLock

Slide 54/60. Copyright c○ 2013, Oracle and/or its affiliates. All rights reserved.

Page 55: What's new in java.util.concurrent

ConcurrentHashMap: Часть JDK 8

Часть методов появилась в других мапах черезdefault-реализации в Map

putIfAbsent(), computeIfAbsent() атомарны в CHMДобавились новые методы и возможности

map.merge(key, valueSuffix, String::concat)chm.values().parallelStream()

Можно использовать лямбды и method referenceint2IntMap.computeIfAbsent(100, (k)->k/3)

theMap::get можно использовать для... map()

Slide 55/60. Copyright c○ 2013, Oracle and/or its affiliates. All rights reserved.

Page 56: What's new in java.util.concurrent

LongAdderTable: Задача

Регистрировать распределение объектовМоделированиеПрофилирование

Slide 56/60. Copyright c○ 2013, Oracle and/or its affiliates. All rights reserved.

Page 57: What's new in java.util.concurrent

LongAdderTable: Решение

Естественное использование LongAdderConcurrentHashMap<K, LongAdder>Serializable

Slide 57/60. Copyright c○ 2013, Oracle and/or its affiliates. All rights reserved.

Page 58: What's new in java.util.concurrent

LongAdderTable: API

install(K key)increment(K key)add(K key)sum(K key)и другие

Slide 58/60. Copyright c○ 2013, Oracle and/or its affiliates. All rights reserved.

Page 59: What's new in java.util.concurrent

Заключение: Книги

Java Concurrency in PracticeBrian Goetz, Tim Peierls, Joshua Bloch, Joseph Bowbeer, DavidHolmes, Doug LeaConcurrent Programming in Java: Design Principles andPatternsDoug Lea

Slide 59/60. Copyright c○ 2013, Oracle and/or its affiliates. All rights reserved.

Page 60: What's new in java.util.concurrent

Заключение: Ресурсы

Concurrency JSR-166 Interest Sitehttp://g.oswego.edu/dl/concurrency-interest/JDK 8http://jdk8.java.net/Project Lambdahttp://openjdk.java.net/projects/lambda/JMHhttp://openjdk.java.net/projects/code-tools/jmh/

Slide 60/60. Copyright c○ 2013, Oracle and/or its affiliates. All rights reserved.