Внутренние потоки Java - PullRequest
1 голос
/ 21 февраля 2010

Я давно изучаю внутреннюю часть Java. Мне любопытно узнать и понять, как происходит многопоточность / блокировка в Java.

Таким образом, чтобы получить доступ к синхронизированному методу или синхронизированному блоку, поток должен сначала получить блокировку для объекта. Итак, вот что мне нужно немного больше света.

Итак, всякий раз, когда поток получает блокировку объекта, увеличивает ли он значение семафора внутри себя? Если ответ «да», давайте посмотрим на этот сценарий.

class ABC{ 

    public void method_1(){
        synchronized(xyz){
            ....
        }
    }

    public void method_2(){
        ...
        synchronized(xyz){
            ....
        }
    }
}

Итак, скажем, есть два потока: Threaad 1 и Thread 2. Предполагая, что Thread1 сначала ввел method_1 и, следовательно, получил блокировку для xyz первым. И, скажем сейчас, Thread2 входит в method_2 и пытается получить блокировку на xyz. Что случится? (Согласно мне, Thread2 будет заблокирован, поскольку он обнаружит, что значение семафора объекта> 0)

Дайте мне знать, если мои рассуждения верны.

Ответы [ 3 ]

1 голос
/ 21 февраля 2010

Ваши рассуждения примерно верны. Поток 2 будет заблокирован и будет оставаться заблокированным до тех пор, пока (как минимум) Поток 1 не освободит мьютекс.

Однако блокировка, как правило, не реализуется с использованием обычного семафора с простым счетчиком. Как правило, есть один бит блокировки, который «раздувается» только до полной блокировки, если объект блокируется повторно (например, если Thread1 пытается заблокировать xyz, пока он уже удерживает блокировку для этого объекта) или когда существует конфликт блокировка (например, когда Thread2 пытается заблокировать xyz, в то время как Thread1 заблокировал его).

Но вам не нужно беспокоиться о деталях реализации Java-блокировок ... если только вы сами не внедрили JVM!

1 голос
/ 21 февраля 2010

Другие ответы в значительной степени ответили на ваш вопрос, но для дальнейшего чтения я рекомендую: Java-параллелизм на практике

1 голос
/ 21 февраля 2010

всякий раз, когда поток получает блокировку объекта, увеличивает ли он значение семафора внутри себя?

Специфичная для реализации, но маловероятная, поскольку каждая блокировка может быть получена только один раз, счетчик не нужен. Простое переключение сделает. Я предполагаю, что каждая блокировка содержит ссылку на нить, которой она принадлежит (или ноль).

Обновление: На самом деле, это немного сложнее, чем это. Блокировка также должна поддерживать список потоков, ожидающих ее. Кроме того, поток может временно снять блокировку с помощью механизма ожидания / уведомления (так что в конце концов будет счетчик входов). Кроме того, управление блокировками сильно влияет на производительность, так что возможны все виды оптимизации. Я нашел этот интересный блог кем-то, кто работает над блокировкой JVM.

Итак, скажем, есть два потока: Threaad 1 и Thread 2. Предполагается, что Thread1 первым вошел в method_1 и, следовательно, получил блокировку для xyz первым. И, скажем теперь, Thread2 входит в method_2 и пытается получить блокировку на xyz. Что будет?

Да, поток 2 будет заблокирован, и подождите, пока он в конечном итоге не получит блокировку.

...