synchronized. wait/notify/notifyAll. Как есть примитивы аналоги из пакета j.u.c?
Дальше тезисы:
• synchronized — ключевое слово, обозначающее скоуп критической секции. Можно ставить напротив объявления метода, или в виде блока в коде.
• wait() — ожидание треда до тех пор, пока он не будет разбужен другим тредом через notify/notifyAll.
• У wait() есть перегруженные версии с таймаутами.
• Тред ставится в wait-set на объекте
• Перед вызовом wait() нужно захватить монитор на данном объекте (через synchronized)
• Магия wait() — он отпускает лок на мониторе объекта после вызова, так чтобы в дальнейшем другой тред мог захватить монитор и вызвать notify/notifyAll
• notify() — будит один из ожидающих тредов, но Важно! — лок на объекте не отпускает, т.е ожидающий тред разбужен будет, но с ожиданием входа в критическую секцию объекта (т.к как будто остановился на synchronized). Так что если после notify есть тяжелые операции, это затормозит ожидающий тред, т.к тред с notify еще не отпустил монитор
• notifyAll() — будут разбужены все треды в wait-set, но при этом далее между тредами происходит contention («сражение») за монитор
• Тред на wait() может быть разбужен также через interrupt, или через spurious wake-up, или по таймауту
• Так что условие выполнения, которого ожидает тред, проверяется в цикле while, а не в if
• Примитив-аналог — Condition
Дальше тезисы:
• synchronized — ключевое слово, обозначающее скоуп критической секции. Можно ставить напротив объявления метода, или в виде блока в коде.
• wait() — ожидание треда до тех пор, пока он не будет разбужен другим тредом через notify/notifyAll.
• У wait() есть перегруженные версии с таймаутами.
• Тред ставится в wait-set на объекте
• Перед вызовом wait() нужно захватить монитор на данном объекте (через synchronized)
• Магия wait() — он отпускает лок на мониторе объекта после вызова, так чтобы в дальнейшем другой тред мог захватить монитор и вызвать notify/notifyAll
• notify() — будит один из ожидающих тредов, но Важно! — лок на объекте не отпускает, т.е ожидающий тред разбужен будет, но с ожиданием входа в критическую секцию объекта (т.к как будто остановился на synchronized). Так что если после notify есть тяжелые операции, это затормозит ожидающий тред, т.к тред с notify еще не отпустил монитор
• notifyAll() — будут разбужены все треды в wait-set, но при этом далее между тредами происходит contention («сражение») за монитор
• Тред на wait() может быть разбужен также через interrupt, или через spurious wake-up, или по таймауту
• Так что условие выполнения, которого ожидает тред, проверяется в цикле while, а не в if
• Примитив-аналог — Condition
👍17🔥5
Что будет в результате компиляции и выполнения данного кода?
Anonymous Quiz
28%
c
29%
a b c
9%
c b a
34%
Ошибка компиляции
👍21
volatile. happens-before.
• Ключевое слово volatile устанавливает отношение happens-before над операциями записи-чтения на поле
• Таким образом, операции чтения из читающих тредов будут видеть эффекты записи пишущих тредов.
• В частности, решается проблема double checked locking. Для double/long типов есть проблема атомарности, она решается через атомики
• Ключевое слово volatile устанавливает отношение happens-before над операциями записи-чтения на поле
• Таким образом, операции чтения из читающих тредов будут видеть эффекты записи пишущих тредов.
• В частности, решается проблема double checked locking. Для double/long типов есть проблема атомарности, она решается через атомики
👍18🔥3⚡1
Что будет выведено в результате выполнения кода?
Anonymous Quiz
9%
int
36%
Object
32%
Integer
23%
Ошибка компиляции
👍24🐳6🔥4🎉1
👍28⚡5🔥3
👍32❤🔥2👎2
AtomicInteger, AtomicLong, AtomicBoolean, AtomicDouble
• Атомики предоставляют возможность изменения переменной в нескольких потоках без эффекта гонок.
• Например, 10 тредов инкрементят AtomicInt = 0, основной тред ждет их выполнения через countdown-latch, далее проверка атомика должна показать 10.
• Основной механизм под капотом атомиков — цикл cas (compare-and-set). На примере increment:
1. Читаем старое значение
2. Перед set'ом проверяем старое значение, если оно не изменилось, сетаем старое + 1
3. Если изменилось, в след. итерации получаем «новое» старое, далее см. п. 1
• Атомики предоставляют возможность изменения переменной в нескольких потоках без эффекта гонок.
• Например, 10 тредов инкрементят AtomicInt = 0, основной тред ждет их выполнения через countdown-latch, далее проверка атомика должна показать 10.
• Основной механизм под капотом атомиков — цикл cas (compare-and-set). На примере increment:
1. Читаем старое значение
2. Перед set'ом проверяем старое значение, если оно не изменилось, сетаем старое + 1
3. Если изменилось, в след. итерации получаем «новое» старое, далее см. п. 1
👍26⚡5🔥1
Что будет выведено в результате выполнения данного кода ?
Anonymous Quiz
5%
current version: 0.1a
66%
current version: 0.5b
8%
current version: 0.1a current version: 0.5b
21%
Ошибка компиляции
👍23🔥4
ReentrantLock
Примитив синхронизации, с помощью которого можно установить границы критической секции. Тред, перед входом в критическую секцию должен сделать захват c операцией lock(), после выхода из крит. секции — сделать unlock(). Другой тред в это время ожидает на lock'е (можно указывать таймаут ожидания), либо может проверить доступность через tryLock().
ReentrantLock обязательно нужно освобождать (такое кол-во раз, сколько раз он был захвачен), в противном случае будет thread starvation у других тредов, ожидающих у границы критической секции.
ReentrantLock может быть «честным» (fairness = true), тогда приоритет отдается тредам, ждущих на нем наибольшее кол-во времени, но это вроде как уменьшает производительность
Примитив синхронизации, с помощью которого можно установить границы критической секции. Тред, перед входом в критическую секцию должен сделать захват c операцией lock(), после выхода из крит. секции — сделать unlock(). Другой тред в это время ожидает на lock'е (можно указывать таймаут ожидания), либо может проверить доступность через tryLock().
ReentrantLock обязательно нужно освобождать (такое кол-во раз, сколько раз он был захвачен), в противном случае будет thread starvation у других тредов, ожидающих у границы критической секции.
ReentrantLock может быть «честным» (fairness = true), тогда приоритет отдается тредам, ждущих на нем наибольшее кол-во времени, но это вроде как уменьшает производительность
lock.lock(); // block until condition holds
try {
// ... method body
} finally {
lock.unlock()
}👍20🔥2
Какой результат работы программы?
Anonymous Quiz
48%
1 2
1%
2 1
4%
Ошибка времени выполнения
47%
Ошибка компиляции
👍32🎉4
Countdown Latch/Cyclic Barrier
CountdownLatch («защелка») — примитив синхронизации, с помощью которого, например, основной thread может ожидать выполнения работы остальных N тредов. Треды, выполняющие работу, выполняют countDown() на защелке, основной тред ожидает на операции await(). Когда счетчик достигает нуля, основной тред продолжает работу.
Для синхронизации N тредов (все ждут всех) и переиспользования используется CyclicBarrier, ему также можно указывать действие (через Runnable), выполняемое после синхронизации всех-со-всеми
CountdownLatch («защелка») — примитив синхронизации, с помощью которого, например, основной thread может ожидать выполнения работы остальных N тредов. Треды, выполняющие работу, выполняют countDown() на защелке, основной тред ожидает на операции await(). Когда счетчик достигает нуля, основной тред продолжает работу.
Для синхронизации N тредов (все ждут всех) и переиспользования используется CyclicBarrier, ему также можно указывать действие (через Runnable), выполняемое после синхронизации всех-со-всеми
👍16
Каким будет результат компиляции и выполнения следующего кода?
Anonymous Quiz
28%
Ошибка выполнения в строке 12
12%
Ошибка выполнения в строке 13
23%
Код успешно скомпилится и выполнится
38%
Ошибка компиляции
👍11❤🔥2
Способы запустить поток?
• Переопределить Thread#run(), запустить через Thread#start()
• new Thread(Runnable).start()
• Через ExecutorService, используя utility-класс Executors
• Переопределить Thread#run(), запустить через Thread#start()
• new Thread(Runnable).start()
• Через ExecutorService, используя utility-класс Executors
👍20🔥6❤🔥2⚡1
Какой будет результат компиляции и выполнения кода?
Anonymous Quiz
53%
I'm child
18%
I'm parent
3%
I'm child I'm parent
6%
I'm parent I'm child
3%
Ошибка выполнения
17%
Ошибка компиляции
👍21🔥8🌭3🌚1