tgoop.com/dev_easy_notes/36
Last Update:
Happens-before. На каждом собесе где меня спрашивали про многопоточность, задавали вопрос про Happens-before. В целом это не сложная концепция, но порой сложно конкретно ответить на этот вопрос, давай те разберем и эту тему.
Начнем с того, что это не проблема многопоточности, а скорее некоторая абстракция, или даже набор правил. Для наглядности начнем с кода. Представим, что у нас есть две функции operationFirst()
и operationSecond()
, которые что-то делают, как-то изменяют состояние объекта:
class Some {
private var x = 0
private var y = 0
fun operationFirst(){
x++
}
fun operationSecond(){
y++
}
}
Далее у нас есть два потока, поток first и поток second, функция operationFirst()
вызывается в потоке first, функция operationSecond()
вызывается в потоке Second.
val some = Some()
val first = thread { some.operationFirst() }
val second = thread { some.operationSecond() }
Теперь следим за руками, если сказано, что operationFirst() happens-before operationSecond()
это означает что все изменения, которые сделал поток first до момента вызова функции operationFirst()
и изменения, которые произошли в самой функции operationFirst()
будут видны потоку second в момент вызова функции operationSecond()
.
Помните мы разбирали, проблему с Visibility, так вот если сказано, что гарантируется operationFirst() happens-before operationSecond()
, то это значит, что проблемой с Visibility точно не будет, поток second точно увидит актуальное значение переменных. Мы также затрагивали проблему Reordering? Если гарантируется happens-before, то переупорядочивание нам тоже не страшно.
Как использовать это на практике? Самый простой способ просто использовать синхронизацию:
val lock = Lock()
val first = thread { lock.withLock { some.operationFirst() } }
val second = thread { lock.withLock { some.operationSecond() } }
first.join()
second.join()
Представим, что поток first точно запуститься первым. В примере получается, что operationFirst() happens-before operationSecond()
, следовательно, все что будет сделано в потоке first, увидит поток second в момент исполнения функции operationSecond()
.
Для примера, несколько вещей в java в которых гарантируется happens-before:
👉Правило запуска потока. Вызов Thread.start на потоки происходит перед каждым действием в запущенном потоке.
👉Правило мониторного замка. Операция unlock на мониторном замке происходит перед каждой последующей операцией lock на том же самом мониторном замке.
👉Правило финализатора. Завершение конструктора объекта происходит перед началом финализатора этого объекта.
🧐Немного запутанная штука, но по сути достаточно понять что показано в картинке и уметь это как-то объяснить.
BY Dev Easy Notes

Share with your friend now:
tgoop.com/dev_easy_notes/36