What's new in java.util.concurrent

Preview:

DESCRIPTION

 

Citation preview

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

Дмитрий Чуйкоdmitry.chuyko@oracle.com

Outline

Введение

Что нового

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

Locks

Accumulators

Collections

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

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.

Введение

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

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

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.

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

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

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

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

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

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

История: 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.

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

Блокирующиеся (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.

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

Java Concurrency Utilities

ExecutorsSynchronizers CollectionsAtomics Locks Nano time

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

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

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

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

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

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

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

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

История: Concurrent Collections

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

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

История: Task Scheduling Framework

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

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

Что нового

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

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

RuntimeLockSupportUnsafe

JVMIntrinsics

OSpthreads mutex

HardwareCAS

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

Что нового: 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.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Атомарные переменные: 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.

Атомарные переменные: 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.

Атомарные переменные: 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.

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

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

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

Атомарные переменные: 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.

Locks

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

Locks: ReentrantReadWriteLock

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

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

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

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

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

Locks: ReentrantReadWriteLock

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

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

Locks: StampedLock

Пример из javadoc

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

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.

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.

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.

Locks: StampedLock

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

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

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

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

Locks: StampedLock

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

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

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

Accumulators

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

Accumulators: Задача

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

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

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.

Accumulators: AtomicLong

SharingSpin loop + CAS, много

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

Accumulators: LongAdder

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

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

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.

Accumulators: DoubleAdder

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

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

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.

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.

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.

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.

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

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

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

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

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

Collections

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

ConcurrentHashMap: CHMv7

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

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

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

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

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.

ConcurrentHashMap: CHMv8 vs CHMv7

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

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

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.

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.

LongAdderTable: Задача

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

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

LongAdderTable: Решение

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

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

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.

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

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.

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

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.