talk juc jeeconf

68
Что нового в j.u.c (JSR 166e) Дмитрий Чуйко [email protected]

Upload: dmitry-chuyko

Post on 15-Jun-2015

677 views

Category:

Documents


1 download

TRANSCRIPT

Page 1: Talk juc jeeconf

Что нового в j.u.c(JSR 166e)

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

Page 2: Talk juc jeeconf

Outline

Введение

Что нового

Atomics

Locks

Accumulators

Collections

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

Page 3: Talk juc jeeconf

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.

Page 4: Talk juc jeeconf

Введение

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

Page 5: Talk juc jeeconf

Введение: Ситуация

� Всем нужны масштабируемость, надёжность,производительность

� The Free Lunch Is Over, Herb Sutter, 2005� Многопоточность может возникать из-за

условий задачи� Многопроцессорность/многоядерность везде

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

Page 6: Talk juc jeeconf

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

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

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

Page 7: Talk juc jeeconf

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

Page 8: Talk juc jeeconf

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

Java Concurrency Utilities

ExecutorsSynchronizers CollectionsAtomics Locks Nano time

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

Page 9: Talk juc jeeconf

История: Фундамент

RuntimeLockSupportUnsafe

JVMIntrinsics

OSpthreads mutex

HardwareCAS

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

Page 10: Talk juc jeeconf

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

� Обёртки примитивов, ссылок, управлениеполями

– Compare-And-Set– Атомарная арифметика

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

Page 11: Talk juc jeeconf

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

� Semaphores, mutexes, barriers, latches,exchangers

– Удобство синхронизации� Locks

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

synchronized– Гибкость

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

Page 12: Talk juc jeeconf

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

Page 13: Talk juc jeeconf

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

Page 14: Talk juc jeeconf

История: Task Scheduling@since 1.5, @since 1.7

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

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

Page 15: Talk juc jeeconf

Что нового

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

Page 16: Talk juc jeeconf

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

Page 17: Talk juc jeeconf

Atomics

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

Page 18: Talk juc jeeconf

Atomics: Чего не хватает

� Для каких примитивных типов нетAtomic-типов?

� В каких числах чаще всего считаем?� Возникают массивы атомарных данных

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

Page 19: Talk juc jeeconf

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.

Page 20: Talk juc jeeconf

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.

Page 21: Talk juc jeeconf

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.

Page 22: Talk juc jeeconf

Atomics: AtomicDoubleArray

� Тест производительности– Размер массива 2, 621, 440– Читатели делают get()– Писатели делают compareAndSet()– Произвольный равномерный доступ

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

Page 23: Talk juc jeeconf

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.

Page 24: Talk juc jeeconf

Locks

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

Page 25: Talk juc jeeconf

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

� Блокировка на чтение, на запись� Чтение без блокировки� Upgrade/downgrade (RL↔WL)� Простота использования� И чтобы быстро работало

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

Page 26: Talk juc jeeconf

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.

Page 27: Talk juc jeeconf

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.

Page 28: Talk juc jeeconf

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.

Page 29: Talk juc jeeconf

Locks: StampedLock@since 1.8

� Пример из javadoc

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

Page 30: Talk juc jeeconf

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.

Page 31: Talk juc jeeconf

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.

Page 32: Talk juc jeeconf

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.

Page 33: Talk juc jeeconf

Locks: StampedLock

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

блокировку– Обычно удачные

� Выигрыш– Мало записей ⇒ в разы– Нет записей ⇒ на порядки– Вне блокировки проверенное состояние может

стать неактуальным

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

Page 34: Talk juc jeeconf

Locks: StampedLock

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

блокировку– Обычно удачные

� Выигрыш– Мало записей ⇒ в разы– Нет записей ⇒ на порядки– Вне блокировки проверенное состояние может

стать неактуальным

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

Page 35: Talk juc jeeconf

Locks: StampedLock

� Повышение уровня блокировки– Может не быть выигрыша, если не

ограничивать запись– Валидное состояние

� В штатном варианте может быть в разыбыстрее RRWL

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

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

Page 36: Talk juc jeeconf

Locks: StampedLock

� Повышение уровня блокировки– Может не быть выигрыша, если не

ограничивать запись– Валидное состояние

� В штатном варианте может быть в разыбыстрее RRWL

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

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

Page 37: Talk juc jeeconf

Accumulators

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

Page 38: Talk juc jeeconf

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.

Page 39: Talk juc jeeconf

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.

Page 40: Talk juc jeeconf

Accumulators: AtomicLong

� Sharing� Spin loop + CAS, много

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

Page 41: Talk juc jeeconf

Accumulators: LongAdder

� Защита от коллизий за счёт структуры иалгоритма

– PaddedAtomicLong[runtime.availableProcessors()]

� Простой API� Number

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

Page 42: Talk juc jeeconf

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.

Page 43: Talk juc jeeconf

Accumulators: DoubleAdder

� Аналогичен LongAdder, только для double� Большая часть логики одинаковая

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

Page 44: Talk juc jeeconf

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.

Page 45: Talk juc jeeconf

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.

Page 46: Talk juc jeeconf

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.

Page 47: Talk juc jeeconf

Accumulators: LongMaxUpdater

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

– accumulate(nextLocalLongMax)

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

Page 48: Talk juc jeeconf

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.

Page 49: Talk juc jeeconf

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

� Local, ThreadLocal – эффективнее, еслиможно применить

� get(), reset() под нагрузкой просаживаютпроизводительность

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

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

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

Page 50: Talk juc jeeconf

Collections

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

Page 51: Talk juc jeeconf

ConcurrentHashMap: CHMv7

� Lock striping– Concurrency level– Сегмент - ReentrantLock

� get() без блокировки� Защита от алгоритмических атак

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

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

Page 52: Talk juc jeeconf

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.

Page 53: Talk juc jeeconf

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.

Page 54: Talk juc jeeconf

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.

Page 55: Talk juc jeeconf

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.

Page 56: Talk juc jeeconf

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.

Page 57: Talk juc jeeconf

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.

Page 58: Talk juc jeeconf

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.

Page 59: Talk juc jeeconf

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.

Page 60: Talk juc jeeconf

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.

Page 61: Talk juc jeeconf

LongAdderTable: Решение

� Естественная комбинация– new ConcurrentHashMap<K, LongAdder>()

� Простой API� Serializable

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

Page 62: Talk juc jeeconf

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.

Page 63: Talk juc jeeconf

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

� 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.

Page 64: Talk juc jeeconf

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

� 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.

Page 65: Talk juc jeeconf

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

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

напрямую

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

Page 66: Talk juc jeeconf

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

� Не часть языка– Обход JMM– sun.misc

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

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

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

Page 67: Talk juc jeeconf

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

� Новая механика– storeFence()

– loadFence()

– fullFence()

– Использование в реализации Locks

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

Page 68: Talk juc jeeconf

Низкоуровневые 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.