Скажем, у меня три потока, нить 1, нить 2 и нить 3, разделяющие одну и ту же блокировку. Thread 2 получает блокировку, выполняет некоторую работу и затем блокирует вызов по методу ожидания. Затем поток 1 получает блокировку, выполняет некоторую работу, и в середине ее поток 3 пытается получить блокировку, но заблокирован, так как поток 1 удерживает ее. Резьба 1 заканчивает работу и, перед завершением, сигнализирует нить 2, что она может повторно зафиксировать замок. Так что же тогда происходит? Будет ли поток 2 или нить 3 приобретать замок дальше?
Большое вам спасибо за ваше время и помощь заранее.
Если приоритет не задан, тот, кто приходит первым, получит замок.
В то время как mutual exclusion
может обеспечить safety
, оно не гарантирует liveness
. Могут быть случаи, когда поток продолжает набирать блокировку, что приводит к starvation
(другие потоки ждут вечно, потому что кто-то продолжает занимать).
Google с выделенными ключевыми словами поможет вам понять больше. Я нашел эти слайды действительно всеобъемлющими http://www.cs.cornell.edu/Courses/cs414/2004su/slides/05_schedule.pdf
Если вы используете ReentrantLock (или любой из его подклассов), вы можете передать флаг "справедливости" конструктору. Если установлено значение true, это гарантирует, что управление блокировкой пройдет до самого длинного ожидающего потока, в этом случае ваш Thread 1.
Lock lock = new ReentrantLock(true);
nofity()
илиnotifyAll()
, нет положения, указывающего, какой ожидающий поток получит блокировку. Таким образом, в вашем примере поток 2 или поток 3 могут получить следующую блокировку. docs.oracle.com/javase/8/docs/api/java/lang/...