Download - What's new in java.util.concurrent
Обзор нововведений в j.u.c(JSR 166e)
Дмитрий Чуйко[email protected]
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.