Talk juc jeeconf
-
Upload
dmitry-chuyko -
Category
Documents
-
view
679 -
download
1
Transcript of Talk juc jeeconf
Что нового в j.u.c(JSR 166e)
Дмитрий Чуйко[email protected]
Outline
Введение
Что нового
Atomics
Locks
Accumulators
Collections
Slide 2/57. Copyright c○ 2013, Oracle and/or its affiliates. All rights reserved.
The following is intended to outline our generalproduct direction. It is intended for informationpurposes only, and may not be incorporated into anycontract. It is not a commitment to deliver anymaterial, code, or functionality, and should not berelied upon in making purchasing decisions. Thedevelopment, release, and timing of any features orfunctionality described for Oracle’s products remainsat the sole discretion of Oracle.
Slide 3/57. Copyright c○ 2013, Oracle and/or its affiliates. All rights reserved.
Введение
Slide 4/57. Copyright c○ 2013, Oracle and/or its affiliates. All rights reserved.
Введение: Ситуация
� Всем нужны масштабируемость, надёжность,производительность
� The Free Lunch Is Over, Herb Sutter, 2005� Многопоточность может возникать из-за
условий задачи� Многопроцессорность/многоядерность везде
Slide 5/57. Copyright c○ 2013, Oracle and/or its affiliates. All rights reserved.
История: Цели
� Параллелизация за кулисами� Загрузка процессора полезной работой� Хорошие алгоритмы
Slide 6/57. 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 ! Deques, !
JSRs
! JSR 166x
2011
JDK 7 ! ForkJoinPool,!
JSRs
! JSR 166y
JDK 8
! java.util.concurrent
JSRs
! JSR 166e
Slide 7/57. Copyright c○ 2013, Oracle and/or its affiliates. All rights reserved.
История: Состав
Java Concurrency Utilities
ExecutorsSynchronizers CollectionsAtomics Locks Nano time
Slide 8/57. Copyright c○ 2013, Oracle and/or its affiliates. All rights reserved.
История: Фундамент
RuntimeLockSupportUnsafe
JVMIntrinsics
OSpthreads mutex
HardwareCAS
Slide 9/57. Copyright c○ 2013, Oracle and/or its affiliates. All rights reserved.
История: Атомарные переменные@since 1.5
� Обёртки примитивов, ссылок, управлениеполями
– Compare-And-Set– Атомарная арифметика
Slide 10/57. Copyright c○ 2013, Oracle and/or its affiliates. All rights reserved.
История: Синхронизация@since 1.5
� Semaphores, mutexes, barriers, latches,exchangers
– Удобство синхронизации� Locks
– Производительность– Модель памяти. Эффект эквивалентен
synchronized– Гибкость
Slide 11/57. Copyright c○ 2013, Oracle and/or its affiliates. All rights reserved.
История: Concurrent Collections@since 1.5
� ArrayBlockingQueue, PriorityBlockingQueue,LinkedBlockingQueue, SynchronousQueue,DelayQueue
� ConcurrentHashMap� CopyOnWriteArrayList� CopyOnWriteArraySet
Slide 12/57. Copyright c○ 2013, Oracle and/or its affiliates. All rights reserved.
История: Concurrent Collections@since 1.6, @since 1.7
� LinkedBlockingDeque, LinkedTransferQueue� ConcurrentSkipListMap� ConcurrentSkipListSet
Slide 13/57. Copyright c○ 2013, Oracle and/or its affiliates. All rights reserved.
История: Task Scheduling@since 1.5, @since 1.7
� Executor’ы– Выполнение асинхронных задач– Политики выполнения
Slide 14/57. Copyright c○ 2013, Oracle and/or its affiliates. All rights reserved.
Что нового
Slide 15/57. Copyright c○ 2013, Oracle and/or its affiliates. All rights reserved.
Что нового: JC Utilities
ExecutorsForkJoinPool (updated, CountedCompleter)
Collections AccumulatorsConcurrentHashMap (v8) LongAccumulator DoubleAccumulator
LongAdder DoubleAdder
LongAdderTable
Locks Atomics SynchronizersStampedLock AtomicDoubleArray CompletableFuture
AtomicDouble
Slide 16/57. Copyright c○ 2013, Oracle and/or its affiliates. All rights reserved.
Atomics
Slide 17/57. Copyright c○ 2013, Oracle and/or its affiliates. All rights reserved.
Atomics: Чего не хватает
� Для каких примитивных типов нетAtomic-типов?
� В каких числах чаще всего считаем?� Возникают массивы атомарных данных
Slide 18/57. Copyright c○ 2013, Oracle and/or its affiliates. All rights reserved.
Atomics: AtomicDouble@since 1.8
� Брат-близнец AtomicLong� Number, Serializable� compareAndSet(double expect, double update)� addAndGet(double delta)� Равенство битов значений
– doubleToRawLongBits()
Slide 19/57. Copyright c○ 2013, Oracle and/or its affiliates. All rights reserved.
Atomics: AtomicDoubleArray@since 1.8
� Брат-близнец AtomicLongArray� Serializable� compareAndSet(int i, double exp, double upd)� addAndGet(int i, double delta)� Равенство битов значений
– doubleToRawLongBits()
Slide 20/57. Copyright c○ 2013, Oracle and/or its affiliates. All rights reserved.
Atomics: Performance
� Приводимые результаты– Intel R○ Xeon R○ E5-2680 (2x8x2, 2.7 GHz)– Linux x64 (RHEL 5.5, kernel 2.6.32)– JDK 7 (1.7.0_11)– OpenJDK JMH 1.0
Slide 21/57. Copyright c○ 2013, Oracle and/or its affiliates. All rights reserved.
Atomics: AtomicDoubleArray
� Тест производительности– Размер массива 2, 621, 440– Читатели делают get()– Писатели делают compareAndSet()– Произвольный равномерный доступ
Slide 22/57. Copyright c○ 2013, Oracle and/or its affiliates. All rights reserved.
Atomics: 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 23/57. Copyright c○ 2013, Oracle and/or its affiliates. All rights reserved.
Locks
Slide 24/57. Copyright c○ 2013, Oracle and/or its affiliates. All rights reserved.
Locks: Чего бы хотелось
� Блокировка на чтение, на запись� Чтение без блокировки� Upgrade/downgrade (RL↔WL)� Простота использования� И чтобы быстро работало
Slide 25/57. Copyright c○ 2013, Oracle and/or its affiliates. All rights reserved.
Locks: ReentrantReadWriteLock@since 1.5
� Lock, блокировка на чтение, на запись� Повторная входимость (reentrancy)� Пробная блокировка, таймауты,
прерываемость
� Conditions� Fair/unfair� Serializable. . .� Memory effects
Slide 26/57. Copyright c○ 2013, Oracle and/or its affiliates. All rights reserved.
Locks: ReentrantReadWriteLock@since 1.5
� Lock, блокировка на чтение, на запись� Повторная входимость (reentrancy)� Пробная блокировка, таймауты,
прерываемость� Conditions� Fair/unfair� Serializable. . .� Memory effects
Slide 26/57. Copyright c○ 2013, Oracle and/or its affiliates. All rights reserved.
Locks: ReentrantReadWriteLock
� readLock() на чтение, writeLock() назапись
� Попробуйте написать оптимистичное чтение,гарантировать memory effects
� Downgrade WL→RL: захват RL под WL� Внутри работает с ThreadLocal
Slide 27/57. Copyright c○ 2013, Oracle and/or its affiliates. All rights reserved.
Locks: StampedLock@since 1.8
� Пример из javadoc
Slide 28/57. Copyright c○ 2013, Oracle and/or its affiliates. All rights reserved.
Locks: StampedLockPoint
class Point {private double x, y;private final StampedLock sl = new StampedLock ();...
Slide 29/57. Copyright c○ 2013, Oracle and/or its affiliates. All rights reserved.
Locks: StampedLockOptimistic Read
double distanceFromOrigin () { // A read -only methodlong stamp = sl.tryOptimisticRead ();double currentX = x;double 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 30/57. Copyright c○ 2013, Oracle and/or its affiliates. All rights reserved.
Locks: StampedLockUpgrade
void moveIfAtOrigin(double newX , double newY) { // upgradelong stamp = sl.readLock (); // Could start with optimistictry {
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 31/57. Copyright c○ 2013, Oracle and/or its affiliates. All rights reserved.
Locks: StampedLock
� Оптимистичное чтение� Если проверки неудачные, можно захватить
блокировку– Обычно удачные
� Выигрыш– Мало записей ⇒ в разы– Нет записей ⇒ на порядки– Вне блокировки проверенное состояние может
стать неактуальным
Slide 32/57. Copyright c○ 2013, Oracle and/or its affiliates. All rights reserved.
Locks: StampedLock
� Оптимистичное чтение� Если проверки неудачные, можно захватить
блокировку– Обычно удачные
� Выигрыш– Мало записей ⇒ в разы– Нет записей ⇒ на порядки– Вне блокировки проверенное состояние может
стать неактуальным
Slide 32/57. Copyright c○ 2013, Oracle and/or its affiliates. All rights reserved.
Locks: StampedLock
� Повышение уровня блокировки– Может не быть выигрыша, если не
ограничивать запись– Валидное состояние
� В штатном варианте может быть в разыбыстрее RRWL
– Не гарантировано!– При этом потребляет меньше ресурсов– Можно передавать метку
Slide 33/57. Copyright c○ 2013, Oracle and/or its affiliates. All rights reserved.
Locks: StampedLock
� Повышение уровня блокировки– Может не быть выигрыша, если не
ограничивать запись– Валидное состояние
� В штатном варианте может быть в разыбыстрее RRWL
– Не гарантировано!– При этом потребляет меньше ресурсов– Можно передавать метку
Slide 33/57. Copyright c○ 2013, Oracle and/or its affiliates. All rights reserved.
Accumulators
Slide 34/57. Copyright c○ 2013, Oracle and/or its affiliates. All rights reserved.
Accumulators: Задача
� Инкрементируем счётчик в разных нитях� Нити подбирают работу и имеют доступ к
общему контекстуvoid call() { // N threads
...invocations.increment ();
}...long getCount () {
return invocations.get();}
� Что использовать для invocations?
Slide 35/57. Copyright c○ 2013, Oracle and/or its affiliates. All rights reserved.
Accumulators: Простое решение
AtomicLong invocations = new AtomicLong (0L); // context...void call() { // N threads
...invocations.getAndIncrement ();
}...long getCount () { // cumulative value
return invocations.get();}
Slide 36/57. Copyright c○ 2013, Oracle and/or its affiliates. All rights reserved.
Accumulators: AtomicLong
� Sharing� Spin loop + CAS, много
Slide 37/57. Copyright c○ 2013, Oracle and/or its affiliates. All rights reserved.
Accumulators: LongAdder
� Защита от коллизий за счёт структуры иалгоритма
– PaddedAtomicLong[runtime.availableProcessors()]
� Простой API� Number
Slide 38/57. Copyright c○ 2013, Oracle and/or its affiliates. All rights reserved.
Accumulators: Решение
LongAdder invocations = new LongAdder (); // context...void call() { // N threads
...invocations.increment ();
}...long getCount () { // cumulative value
return invocations.sum();}
Slide 39/57. Copyright c○ 2013, Oracle and/or its affiliates. All rights reserved.
Accumulators: DoubleAdder
� Аналогичен LongAdder, только для double� Большая часть логики одинаковая
Slide 40/57. 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 41/57. Copyright c○ 2013, Oracle and/or its affiliates. All rights reserved.
Accumulators: Произвольныекоммутативные операции
� LongAccumulatorLongAccumulator invocations =new LongAccumulator(Long::sum , 0L); // context...void call() { // N threads
...invocations.accumulate (1);
}...long getCount () { // cumulative value
return invocations.get();}
� DoubleAccumulator
Slide 42/57. Copyright c○ 2013, Oracle and/or its affiliates. All rights reserved.
Accumulators: Atomics
� AtomicXXX– updateAndGet(current -> current + 1)
– getAndAccumulate(delta, (current, delta) -> current+delta)
Slide 43/57. Copyright c○ 2013, Oracle and/or its affiliates. All rights reserved.
Accumulators: LongMaxUpdater
� LongAccumulator(Long::max, Long.MIN_VALUE)� Тест производительности
– accumulate(nextLocalLongMax)
Slide 44/57. 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 45/57. Copyright c○ 2013, Oracle and/or its affiliates. All rights reserved.
Accumulators: Подводные камни
� Local, ThreadLocal – эффективнее, еслиможно применить
� get(), reset() под нагрузкой просаживаютпроизводительность
– Обход всех ячеек� Границы эффекта
– Система до насыщения– Итерации менее 1 мкс
Slide 46/57. Copyright c○ 2013, Oracle and/or its affiliates. All rights reserved.
Collections
Slide 47/57. Copyright c○ 2013, Oracle and/or its affiliates. All rights reserved.
ConcurrentHashMap: CHMv7
� Lock striping– Concurrency level– Сегмент - ReentrantLock
� get() без блокировки� Защита от алгоритмических атак
– Другой хэш для String
Slide 48/57. Copyright c○ 2013, Oracle and/or its affiliates. All rights reserved.
ConcurrentHashMap: CHMv8
� Lock striping– Concurrency level не используется, подстройка
структуры в процессе работы– Node (bucket): synchronized или StampedLock
� get() без блокировки или под блокировкойна чтение
� Защита от алгоритмических атак– Сбалансированное дерево для Comparable -
performance
Slide 49/57. Copyright c○ 2013, Oracle and/or its affiliates. All rights reserved.
ConcurrentHashMap: CHMv8
� Lock striping– Concurrency level не используется, подстройка
структуры в процессе работы– Node (bucket): synchronized или StampedLock
� get() без блокировки или под блокировкойна чтение
� Защита от алгоритмических атак– Сбалансированное дерево для Comparable -
performance
Slide 49/57. Copyright c○ 2013, Oracle and/or its affiliates. All rights reserved.
ConcurrentHashMap: CHMv8
� Lock striping– Concurrency level не используется, подстройка
структуры в процессе работы– Node (bucket): synchronized или StampedLock
� get() без блокировки или под блокировкойна чтение
� Защита от алгоритмических атак– Сбалансированное дерево для Comparable -
performance
Slide 49/57. Copyright c○ 2013, Oracle and/or its affiliates. All rights reserved.
ConcurrentHashMap: v8 vs v7
� Тест производительности– put()– Integer-like ключи– Нормальное распределение– 2, 621, 440 элементов– concurrencyLevel == 32 (optimal)
Slide 50/57. 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 51/57. 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()
� Можно использовать лямбды и methodreference
– int2IntMap.computeIfAbsent(100, (k)->k/3)
– stream.map(theMap::get)
Slide 52/57. 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()
� Можно использовать лямбды и methodreference
– int2IntMap.computeIfAbsent(100, (k)->k/3)
– stream.map(theMap::get)
Slide 52/57. 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()
� Можно использовать лямбды и methodreference
– int2IntMap.computeIfAbsent(100, (k)->k/3)
– stream.map(theMap::get)
Slide 52/57. Copyright c○ 2013, Oracle and/or its affiliates. All rights reserved.
LongAdderTable: Задача
� Регистрировать распределение объектов– Моделирование– Профилирование
void call() { // N threads...invocations.increment("call");
}...long getCount(String name) { // cumulative value
return invocations.sum(name);}
Slide 53/57. Copyright c○ 2013, Oracle and/or its affiliates. All rights reserved.
LongAdderTable: Решение
� Естественная комбинация– new ConcurrentHashMap<K, LongAdder>()
� Простой API� Serializable
Slide 54/57. 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 55/57. Copyright c○ 2013, Oracle and/or its affiliates. All rights reserved.
Заключение: Книги
� Java Concurrency in PracticeBrian Goetz, Tim Peierls, Joshua Bloch, JosephBowbeer, David Holmes, Doug Lea
� Concurrent Programming in Java: DesignPrinciples and PatternsDoug Lea
Slide 56/57. 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 57/57. Copyright c○ 2013, Oracle and/or its affiliates. All rights reserved.
Низкоуровневые API: Мотивация
� JMM абстрактна, железо конкретно� Есть полезные трюки� Не используйте низкоуровневые API
напрямую
Slide 57/57. Copyright c○ 2013, Oracle and/or its affiliates. All rights reserved.
Низкоуровневые API: Unsafe
� Не часть языка– Обход JMM– sun.misc
� Unsafe API в Hotspot– Аккуратный– Абстрактный– Достаточный
� Не используйте Unsafe напрямую, это unsafe
Slide 57/57. Copyright c○ 2013, Oracle and/or its affiliates. All rights reserved.
Низкоуровневые API: Unsafe
� Новая механика– storeFence()
– loadFence()
– fullFence()
– Использование в реализации Locks
Slide 57/57. Copyright c○ 2013, Oracle and/or its affiliates. All rights reserved.
Низкоуровневые API: StampedLock
Listing 1: Optimistic Read/* volatile long state */...long stamp = sl.tryOptimisticRead (); /* s = state */double currentX = x;double currentY = y;if (!sl.validate(stamp )) { /* unsafe.loadFence () */...
stamp = sl.writeLock (); /* CAS(state , next) */x = newX;y = newY;sl.unlock(stamp );
Slide 57/57. Copyright c○ 2013, Oracle and/or its affiliates. All rights reserved.