Подтвердить что ты не робот

Внутренняя блокировка резьбы

Когда мы говорим о встроенной блокировке, мы ссылаемся на объект, для которого мы запрашиваем блокировку или для синхронизированного метода?

Блокировка находится на объекте или на его методе синхронизации?

Я в замешательстве!

4b9b3361

Ответ 1

Внутренние блокировки находятся на объекте:

class A
{
   public synchronized void method1(){...}
   public synchronized void method2(){...}
}

Если поток A находится в методе 1, то threadB не может ввести метод2.

Ответ 2

В Java внутренняя блокировка подразумевается при каждом использовании синхронизированного ключевого слова

Каждое использование синхронизированного ключевого слова связано с одним из двух типов встроенной блокировки:

"блокировка экземпляра", прикрепленная к одному объекту

a "статический замок", прикрепленный к классу

Если метод объявлен как синхронизированный, он будет получать либо блокировку экземпляра, либо статическую блокировку при ее вызове в зависимости от того, является ли это методом экземпляра или статическим методом.

Два типа блокировки имеют сходное поведение, но полностью независимы друг от друга.

Приобретение блокировки экземпляра блокирует другие потоки только от вызова метода синхронизированного экземпляра; он не блокирует другие потоки от вызова несинхронизированного метода и не блокирует их от вызова статического синхронизированного метода.

Аналогично, получение статической блокировки блокирует другие потоки только от вызова статического синхронизированного метода; он не блокирует другие потоки от вызова несинхронизированного метода и не блокирует их от вызова метода синхронизированных экземпляров.

За пределами заголовка метода синхронизированный (this) получает блокировку экземпляра.

Статическая блокировка может быть получена за пределами заголовка метода двумя способами:

synchronized (Blah.class), используя литерал класса

synchronized (this.getClass()), если объект доступен

Ответ 3

Синхронизированные методы блокируют метод объекта

synchronized void methodA () {
    ....    
}

как-то эквивалентно

void methodA () {
    synchronized (this) {
        ....
    }
}

Ответ 4

Замок является частью объекта. Каждый объект имеет один, и он может быть заблокирован двумя способами:

  • Использование модификатора synchronized для метода экземпляра класса для блокировки связанного объекта
  • Использование блока synchronized(object) {}

Аналогично, вы можете заблокировать класс объекта вместо самого объекта (указывается отдельно, чтобы понять модификатор synchronized с помощью метода static):

  • Использование модификатора synchronized для статического метода класса для блокировки класса
  • Использование блока synchronized(clazz) {}, где clazz - это класс объекта

Ответ 5

Заблокирован объект. В Java каждый объект является monitor

Ответ 6

private int count = 0;
public synchronized void countFunc(){
        count++;
    }
Thread t1 = new Thread(new Runnable(){
            public void run(){
            for(int i=0;i<1000;i++){
                countFunc();
                }}});
        Thread t2 = new Thread(new Runnable(){
            public void run(){
            for(int i=0;i<1000;i++){
                countFunc();
            }}});

В приведенном выше примере у меня есть 2 потока, пытающихся увеличить значение count. И чтобы предотвратить чередование потоков, я пытаюсь захватить внутреннюю блокировку с помощью синхронизированного ключевого слова.

Окончательно, В этом примере блокировка содержит блок countFunc с ключевым словом синхронизированное и блокировка. > на переменной count. Надеюсь, что это поможет

Ответ 7

Замок находится в объекте.

Посмотрите на страницу руководства java на встроенные блокировки

Каждый объект имеет связанный с ним встроенный замок. По соглашению поток, который нуждается в эксклюзивном и последовательном доступе к полям объекта, должен получить внутреннюю блокировку объекта перед доступом к ним, а затем освободить внутреннюю блокировку, когда она будет выполнена с ними. Говорят, что поток имеет собственный замок между временем, когда он приобрел замок, и освободил блокировку.

Пока поток имеет встроенную блокировку, ни один другой поток не может получить одну и ту же блокировку. Другой поток будет блокироваться, когда он попытается получить блокировку.

Два способа использования встроенных замков:

  • Синхронизированные методы:

    Когда поток вызывает метод synchronized, он автоматически получает встроенную блокировку для этого объекта метода и освобождает его при возврате метода.

    например.

    public synchronized void incrementCounter(){
        ++counter;
    }
    
  • Синхронизированные операторы

    В отличие от методов synchronized, операторы synchronized должны указывать объект, который обеспечивает внутреннюю блокировку

    public int getCounter(){
        synchronized(this){
            return counter;
        }
    }
    

    Полный пример:

    public class SynchronizedDemo{
    private int counter = 0;
    
    public SynchronizedDemo(){
    
    }
    public synchronized void incrementCounter(){
        ++counter;
    }
    public int getCounter(){
        synchronized(this){
            return counter;
        }
    }
    public static void main(String[] args){
        SynchronizedDemo object = new SynchronizedDemo();
        for ( int i=0; i < 5; i++){
            Thread t = new Thread(new SimpleRunnable(object));
            t.start();
        }           
    }
    }
    class SimpleRunnable implements Runnable{
    private SynchronizedDemo object;
    
    public SimpleRunnable(SynchronizedDemo obj){
        this.object = obj;
    }
    public void run(){
        object.incrementCounter();
        System.out.println("Counter:"+object.getCounter());
    }
    }
    

Примечание. Этот пример написан только для демонстрации различных способов использования встроенных блокировок. Использование AtomicInteger для переменной счетчика - правильный подход для этого типа прецедента.