multithreading in java past and actual
TRANSCRIPT
![Page 1: Multithreading in java past and actual](https://reader036.vdocuments.us/reader036/viewer/2022062523/58f1495f1a28abe40d8b45d3/html5/thumbnails/1.jpg)
Multithreading in Java past & actual.
April 20, 2016
![Page 2: Multithreading in java past and actual](https://reader036.vdocuments.us/reader036/viewer/2022062523/58f1495f1a28abe40d8b45d3/html5/thumbnails/2.jpg)
2CONFIDENTIAL
• Полуков Євген, Software Engineer у EPAM – разработчик с более 6 годами опыта в ИТ из них более 2 лет в EPAM. На данный момент занимаюсь разработкой e-commerce (Hybris).
Обо Мне
![Page 3: Multithreading in java past and actual](https://reader036.vdocuments.us/reader036/viewer/2022062523/58f1495f1a28abe40d8b45d3/html5/thumbnails/3.jpg)
3CONFIDENTIAL
Введение
Организация данных и задач 1
Параллелизация за кулисами 2
Загрузка процессоров полезной работой3
Хорошие алгоритмы4
Не надо изобретать велосипед5
![Page 4: Multithreading in java past and actual](https://reader036.vdocuments.us/reader036/viewer/2022062523/58f1495f1a28abe40d8b45d3/html5/thumbnails/4.jpg)
4CONFIDENTIAL
О чем будем говорить?
MM and HMA 1
Executors 2
Atomics and Accumulators3
Locks4
Synchronizers5
![Page 5: Multithreading in java past and actual](https://reader036.vdocuments.us/reader036/viewer/2022062523/58f1495f1a28abe40d8b45d3/html5/thumbnails/5.jpg)
5CONFIDENTIAL
История: Java Concurrency TimeLine
![Page 6: Multithreading in java past and actual](https://reader036.vdocuments.us/reader036/viewer/2022062523/58f1495f1a28abe40d8b45d3/html5/thumbnails/6.jpg)
6CONFIDENTIAL
Thread : MM
• Каждий поток имет свой thread stack.
• Вся информация о методах и их вызовах сохраняется в thread stack.
• Все локальные примитивы сохраняются thread stack.
![Page 7: Multithreading in java past and actual](https://reader036.vdocuments.us/reader036/viewer/2022062523/58f1495f1a28abe40d8b45d3/html5/thumbnails/7.jpg)
7CONFIDENTIAL
Thread: MM and HMA
![Page 8: Multithreading in java past and actual](https://reader036.vdocuments.us/reader036/viewer/2022062523/58f1495f1a28abe40d8b45d3/html5/thumbnails/8.jpg)
8CONFIDENTIAL
Thread: MM and HMA какие есть проблемы?
Visibility of Shared Objects Race Conditions
![Page 9: Multithreading in java past and actual](https://reader036.vdocuments.us/reader036/viewer/2022062523/58f1495f1a28abe40d8b45d3/html5/thumbnails/9.jpg)
9CONFIDENTIAL
Thread: Visibility of Shared Objects
• Если у нас возникает работа с общими объектами без использования volatile или synchronization.
• В данном случае нам помогает volatile решить данную проблему.
![Page 10: Multithreading in java past and actual](https://reader036.vdocuments.us/reader036/viewer/2022062523/58f1495f1a28abe40d8b45d3/html5/thumbnails/10.jpg)
10CONFIDENTIAL
Thread: Race Conditions
• Гонка потоков при неатомарных операциях. Если у нас возникает работа с общими объектами без использование synchronization.
• В данном случае нам помогает synchronization решить данную проблему.
![Page 11: Multithreading in java past and actual](https://reader036.vdocuments.us/reader036/viewer/2022062523/58f1495f1a28abe40d8b45d3/html5/thumbnails/11.jpg)
11CONFIDENTIAL
Thread State
![Page 12: Multithreading in java past and actual](https://reader036.vdocuments.us/reader036/viewer/2022062523/58f1495f1a28abe40d8b45d3/html5/thumbnails/12.jpg)
12CONFIDENTIAL
Executors
Возможность выбирать реализацию создания потоков. (newCachedThreadPool, newSingleThreadExecutor, newFixedThreadPool, newSingleThreadScheduledExecutor)
Удобное название потоков (по умолчанию pool-N-thread-N или кастомный ThreadFactory)
Запускать batch (Runnable, Callable)Остановка потоков (shutdown, shutdownNow)
![Page 13: Multithreading in java past and actual](https://reader036.vdocuments.us/reader036/viewer/2022062523/58f1495f1a28abe40d8b45d3/html5/thumbnails/13.jpg)
13CONFIDENTIAL
Executors: ScheduledExecutorService
Запуск потоков по расписаниюschedule(Runnable command, long delay, TimeUnit unit)
scheduleAtFixedRate(Runnable command, long initialDelay, long period, TimeUnit unit)
![Page 14: Multithreading in java past and actual](https://reader036.vdocuments.us/reader036/viewer/2022062523/58f1495f1a28abe40d8b45d3/html5/thumbnails/14.jpg)
14CONFIDENTIAL
Executors: ScheduledExecutorService
service = Executors.newSingleThreadScheduledExecutor();если требуется отложить выполнение на 5 секунд
service.schedule(()-> { ... }, 5, TimeUnit.SECONDS);Если требуется назначить выполнение каждую секунду:
service.scheduleAtFixedRate(() -> { ... }, 0, 1, TimeUnit.SECONDS);
Eсли требуется назначить выполнение кода с промежутком 1 секунда между выполнениями:service.scheduleWithFixedDelay(()-> { ... }, 0, 1, TimeUnit.SECONDS);
![Page 15: Multithreading in java past and actual](https://reader036.vdocuments.us/reader036/viewer/2022062523/58f1495f1a28abe40d8b45d3/html5/thumbnails/15.jpg)
15CONFIDENTIAL
Accumulators
Инкрементируем счетчик в разных потоках.
Узнать статистику - сколько потоков имеют доступ к общему методу.
public void run() { ... counter.incrementAndGet();}
public long getCount() { return counter.get();}
Что использовать для counter?
![Page 16: Multithreading in java past and actual](https://reader036.vdocuments.us/reader036/viewer/2022062523/58f1495f1a28abe40d8b45d3/html5/thumbnails/16.jpg)
16CONFIDENTIAL
Accumulators
![Page 17: Multithreading in java past and actual](https://reader036.vdocuments.us/reader036/viewer/2022062523/58f1495f1a28abe40d8b45d3/html5/thumbnails/17.jpg)
17CONFIDENTIAL
Accumulators: LongAdder
Защита от коллизий за счет структуры и алгоритма
@sun.misc.Contended class Cellcells: PaddedAtomicLong[availableProcessors()]
hash: Thread.threadLocalHandonProbeПростой API
![Page 18: Multithreading in java past and actual](https://reader036.vdocuments.us/reader036/viewer/2022062523/58f1495f1a28abe40d8b45d3/html5/thumbnails/18.jpg)
18CONFIDENTIAL
Accumulators: LongAdder
final LongAdder counter = new LongAdder();
public void run() { ... counter.increment();}
public long getCount() { return counter.sum();}
![Page 19: Multithreading in java past and actual](https://reader036.vdocuments.us/reader036/viewer/2022062523/58f1495f1a28abe40d8b45d3/html5/thumbnails/19.jpg)
19CONFIDENTIAL
Accumulators: LongAdder: Подводные камни
get(), reset(), sum() под нагрузкой просаживают производительность из - за обхода всех ячеек.
![Page 20: Multithreading in java past and actual](https://reader036.vdocuments.us/reader036/viewer/2022062523/58f1495f1a28abe40d8b45d3/html5/thumbnails/20.jpg)
20CONFIDENTIAL
Accumulators: Atomic Update
/*** Atomically adds the given value to the current value.** @param delta the value to add* @return the previous value*/public final int getAndAdd(int delta) { for (;;) { int current = get(); int next = current + delta; if (compareAndSet(current, next)) return current; }}
![Page 21: Multithreading in java past and actual](https://reader036.vdocuments.us/reader036/viewer/2022062523/58f1495f1a28abe40d8b45d3/html5/thumbnails/21.jpg)
21CONFIDENTIAL
Accumulators
![Page 22: Multithreading in java past and actual](https://reader036.vdocuments.us/reader036/viewer/2022062523/58f1495f1a28abe40d8b45d3/html5/thumbnails/22.jpg)
22CONFIDENTIAL
Accumulators: LongAccumulator
final LongAccumulator counter = new LongAccumulator(
(left, right) -> left * right, 2l );
//LongBinaryOperator//final LongAccumulator counter = new LongAccumulator(
Long::sum, 0l
);//final AtomicLong counter = new AtomicLong(0);
public void run() { counter.accumulate(1); //counter.updateAndGet(counter->counter+1);}
public long getCount() { return counter.get();}
![Page 23: Multithreading in java past and actual](https://reader036.vdocuments.us/reader036/viewer/2022062523/58f1495f1a28abe40d8b45d3/html5/thumbnails/23.jpg)
23CONFIDENTIAL
Locks
Блокировка на чтение, на записьЧтение без блокировкиКонвертация (RW <->WR)Простота использованияИ чтобы быстро работало
Чего бы хотелось
![Page 24: Multithreading in java past and actual](https://reader036.vdocuments.us/reader036/viewer/2022062523/58f1495f1a28abe40d8b45d3/html5/thumbnails/24.jpg)
24CONFIDENTIAL
Locks: ReentrantReadWriteLock
Lock, блокировка на чтение, на запись
Рекурсивный захват Пробная блокировка, таймауты прерываемость
УсловияЧестная/Нечестная
![Page 25: Multithreading in java past and actual](https://reader036.vdocuments.us/reader036/viewer/2022062523/58f1495f1a28abe40d8b45d3/html5/thumbnails/25.jpg)
25CONFIDENTIAL
Locks: ReentrantReadWriteLock
AbstractQueuedSynchronizerАтомарное состояние: volatile int stateОчередь ожидания с атомарными обновлениями
ThreadLocal<HoldCounter>Инкапсуляция полная
Что внутри
![Page 26: Multithreading in java past and actual](https://reader036.vdocuments.us/reader036/viewer/2022062523/58f1495f1a28abe40d8b45d3/html5/thumbnails/26.jpg)
26CONFIDENTIAL
Locks
![Page 27: Multithreading in java past and actual](https://reader036.vdocuments.us/reader036/viewer/2022062523/58f1495f1a28abe40d8b45d3/html5/thumbnails/27.jpg)
27CONFIDENTIAL
Locks: StampedLock
Lock, блокировка на чтение, на запись
Оптимистическое чтениеКонвертация (RW <->WR)
![Page 28: Multithreading in java past and actual](https://reader036.vdocuments.us/reader036/viewer/2022062523/58f1495f1a28abe40d8b45d3/html5/thumbnails/28.jpg)
28CONFIDENTIAL
Locks: StampedLock
class Point {private double x, y;private final StampedLock sl = new
StampedLock();
![Page 29: Multithreading in java past and actual](https://reader036.vdocuments.us/reader036/viewer/2022062523/58f1495f1a28abe40d8b45d3/html5/thumbnails/29.jpg)
29CONFIDENTIAL
Locks: StampedLock
void move(double deltaX, double deltaY) { // an exclusively locked method
long stamp = sl.writeLock(); try { x += deltaX; y += deltaY; } finally { sl.unlockWrite(stamp); }}
![Page 30: Multithreading in java past and actual](https://reader036.vdocuments.us/reader036/viewer/2022062523/58f1495f1a28abe40d8b45d3/html5/thumbnails/30.jpg)
30CONFIDENTIAL
Locks: StampedLock
double distanceFromOrigin() { // A read-only method long stamp = sl.readLock(); try { return Math.hypot(x, y); } finally { sl.unlockRead(stamp); }}
![Page 31: Multithreading in java past and actual](https://reader036.vdocuments.us/reader036/viewer/2022062523/58f1495f1a28abe40d8b45d3/html5/thumbnails/31.jpg)
31CONFIDENTIAL
Locks: StampedLock
double 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);}
![Page 32: Multithreading in java past and actual](https://reader036.vdocuments.us/reader036/viewer/2022062523/58f1495f1a28abe40d8b45d3/html5/thumbnails/32.jpg)
32CONFIDENTIAL
Locks: StampedLock
void moveIfAtOrigin(double newX, double newY) { long stamp = sl.writeLock(); try { if (x == 0.0 && y == 0.0) { x = newX; y = newY; } } finally { sl.unlockWrite(stamp); }}
![Page 33: Multithreading in java past and actual](https://reader036.vdocuments.us/reader036/viewer/2022062523/58f1495f1a28abe40d8b45d3/html5/thumbnails/33.jpg)
33CONFIDENTIAL
Locks: StampedLock
long stamp = sl.readLock(); // Could instead start with optimistic, not read mode
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);
![Page 34: Multithreading in java past and actual](https://reader036.vdocuments.us/reader036/viewer/2022062523/58f1495f1a28abe40d8b45d3/html5/thumbnails/34.jpg)
34CONFIDENTIAL
Locks: StampedLock
Оптимистическое чтениеЕсли проверки неудачные, можно захватить блокировку
Конвертация (RW <->WR)native U.loadFance(), U.getLongVolatail();
![Page 35: Multithreading in java past and actual](https://reader036.vdocuments.us/reader036/viewer/2022062523/58f1495f1a28abe40d8b45d3/html5/thumbnails/35.jpg)
35CONFIDENTIAL
Synchronizers
CountDownLatchCyclicBarrierSemaphoreExchanger
![Page 36: Multithreading in java past and actual](https://reader036.vdocuments.us/reader036/viewer/2022062523/58f1495f1a28abe40d8b45d3/html5/thumbnails/36.jpg)
36CONFIDENTIAL
Synchronizers : CountDownLatch
Позволяет одному или нескольким потокам ожидать до тех пор, пока не завершится определенное количество операций, выполняющих в других потоках.
Может использоваться раз.
![Page 37: Multithreading in java past and actual](https://reader036.vdocuments.us/reader036/viewer/2022062523/58f1495f1a28abe40d8b45d3/html5/thumbnails/37.jpg)
37CONFIDENTIAL
Synchronizers : CountDownLatch
CountDownLatch(int count)void await()boolean await(long timeout, TimeUnit unit)void countDown()
![Page 38: Multithreading in java past and actual](https://reader036.vdocuments.us/reader036/viewer/2022062523/58f1495f1a28abe40d8b45d3/html5/thumbnails/38.jpg)
38CONFIDENTIAL
Synchronizers : CountDownLatch
class Service implements Runnable { private static final int EMULATE_TIME_TO_START = 1000; private final String name; private final CountDownLatch latch;
public void run() { ... sleep(EMULATE_TIME_TO_START); Logger.getLogger(Service.class.getName()).log(
Level.INFO, name + " is Up"); latch.countDown(); //reduce count of CountDownLatch by 1
}}
![Page 39: Multithreading in java past and actual](https://reader036.vdocuments.us/reader036/viewer/2022062523/58f1495f1a28abe40d8b45d3/html5/thumbnails/39.jpg)
39CONFIDENTIAL
Synchronizers : CountDownLatch
public static void main(String args[]) throws InterruptedException {
final CountDownLatch latch = new CountDownLatch(3); final ExecutorService executorService =
Executors.newCachedThreadPool();
executorService.submit(new Service(CACHE, latch)); executorService.submit(new Service(ALERT, latch)); executorService.submit(new Service(GSM, latch)); latch.await(); //main thread is waiting on CountDownLatch to finish
Logger.getLogger(Service.class.getName()).log(Level.INFO, "All services are up,
Application is starting now");}
![Page 40: Multithreading in java past and actual](https://reader036.vdocuments.us/reader036/viewer/2022062523/58f1495f1a28abe40d8b45d3/html5/thumbnails/40.jpg)
40CONFIDENTIAL
Synchronizers : CyclicBarrier
Очень похож на CountDownLatch но при достижение барьера его можно переиспользовать опять.
Возможность выполнить дополнительную логику до достижения барьера.
![Page 41: Multithreading in java past and actual](https://reader036.vdocuments.us/reader036/viewer/2022062523/58f1495f1a28abe40d8b45d3/html5/thumbnails/41.jpg)
41CONFIDENTIAL
Synchronizers : CyclicBarrier
CyclicBarrier(int parties)CyclicBarrier(int parties, Runnable barrierAction)int await()int await(long timeout, TimeUnit unit)void reset()
![Page 42: Multithreading in java past and actual](https://reader036.vdocuments.us/reader036/viewer/2022062523/58f1495f1a28abe40d8b45d3/html5/thumbnails/42.jpg)
42CONFIDENTIAL
Synchronizers : Exchanger
Как видно из названия, основное предназначение данного класса — это обмен объектами между двумя потоками.
При этом, также поддерживаются null значения, что позволяет использовать данный класс для передачи только одного объекта или же просто как синхронизатор двух потоков.
Первый поток, который вызывает метод exchange(...) заблокируется до тех пор, пока тот же метод не вызовет второй поток.
![Page 43: Multithreading in java past and actual](https://reader036.vdocuments.us/reader036/viewer/2022062523/58f1495f1a28abe40d8b45d3/html5/thumbnails/43.jpg)
43CONFIDENTIAL
Synchronizers : Exchanger
class SimpleChat implements Runnable { public SimpleChat(Exchanger<String> exchanger, String message)
{ this.exchanger = exchanger; this.message = message; } public void run() { try { Logger.getLogger(Service.class.getName()).log(Level.INFO,
getName() + " message: " + message); message = exchanger.exchange(message); // exchange messages
} catch (Exception exe) { Logger.getLogger(Service.class.getName()).log(Level.SEVERE,
exe); } }}
![Page 44: Multithreading in java past and actual](https://reader036.vdocuments.us/reader036/viewer/2022062523/58f1495f1a28abe40d8b45d3/html5/thumbnails/44.jpg)
44CONFIDENTIAL
Synchronizers : Exchanger
public static void main(String[] args) { final Exchanger<String> exchanger = new Exchanger<>(); final ExecutorService executorService =
Executors.newCachedThreadPool();
executorService.submit(new SimpleChat(exchanger, "Неплохо
бы завтра в зал. Ну что идем?"));
executorService.submit(new SimpleChat(exchanger, "Да настало
время жать!!!"));
executorService.shutdown();}
![Page 45: Multithreading in java past and actual](https://reader036.vdocuments.us/reader036/viewer/2022062523/58f1495f1a28abe40d8b45d3/html5/thumbnails/45.jpg)
45CONFIDENTIAL
Synchronizers : Semaphore
Используются для ограничения количества потоков при работе с аппаратными ресурсами или файловой системой. Доступ к общему ресурсу управляется с помощью счетчика (permits).
![Page 46: Multithreading in java past and actual](https://reader036.vdocuments.us/reader036/viewer/2022062523/58f1495f1a28abe40d8b45d3/html5/thumbnails/46.jpg)
46CONFIDENTIAL
Synchronizers : Semaphore
Semaphore(int permits)void acquire(); void acquire(int permits)boolean tryAcquire(); boolean tryAcquire(long timeout, TimeUnit unit)void release(); void release(int permits)protected void reducePermits(int reduction)
![Page 47: Multithreading in java past and actual](https://reader036.vdocuments.us/reader036/viewer/2022062523/58f1495f1a28abe40d8b45d3/html5/thumbnails/47.jpg)
47CONFIDENTIAL
Synchronizers : Резюме
CountDownLatch- Делает одноразовую защелку, которую
нельзя обнулитьCyclicBarrier
- Барьер, который сбрасывается, когда он достигнет нуля, можна переиспользовать, плюс выполнять логику, когда барьер достигнут.
Exchanger - Предзназначен для обмена объектами между двумя потоками
![Page 48: Multithreading in java past and actual](https://reader036.vdocuments.us/reader036/viewer/2022062523/58f1495f1a28abe40d8b45d3/html5/thumbnails/48.jpg)
48CONFIDENTIAL
Synchronizers : Резюме
Semaphore- Предназначен для ограничение количества роботы потоков в системе. Узким местом при использовании семафоров является заданное количества разрешений, т.к. зачастую это число приходится подбирать в зависимости от мощности «железа».
![Page 49: Multithreading in java past and actual](https://reader036.vdocuments.us/reader036/viewer/2022062523/58f1495f1a28abe40d8b45d3/html5/thumbnails/49.jpg)
49CONFIDENTIAL
Конец
![Page 50: Multithreading in java past and actual](https://reader036.vdocuments.us/reader036/viewer/2022062523/58f1495f1a28abe40d8b45d3/html5/thumbnails/50.jpg)
50CONFIDENTIAL
Полезные ссылки и книжки
Java Concurrency in Practice 1st Editionhttps://habrahabr.ru/company/luxoft/blog/157273/Effective Java (2nd Edition) 2nd EditionThe Art of Multiprocessor Programming, Revised Reprint 1st Editionhttp://altair.cs.oswego.edu/mailman/listinfo/concurrency-interesthttp://openjdk.java.net/jeps/188http://psy-lob-saw.blogspot.com/