Синхронизированные статические методы Java: блокировка объекта или класса

В учебниках Java говорится: "Невозможно чередование двух вызовов синхронизированных методов на одном объекте".

Что это значит для static method? Поскольку у статического метода нет связанного объекта, будет ли синхронизированная блокировка ключевого слова для класса вместо объекта?

Ответ 1

Поскольку у статического метода нет связанного объекта, будет ли синхронизированная блокировка ключевого слова для класса вместо объекта?

Да.:)

Ответ 2

Просто добавьте немного подробностей в Оскар (приятный лаконичный!) ответ, соответствующий раздел по Спецификации Java Language 8.4.3.6, 'synchronized Methods':

Синхронизированный метод получает монитор (§17.1) перед его выполнением. Для класса (статического) метода используется монитор, связанный с объектом класса для класса метода. Для метода экземпляра используется связанный с ним монитор (объект, для которого был вызван метод).

Ответ 3

Один момент, о котором вы должны быть осторожны (несколько программистов, как правило, попадают в эту ловушку), заключается в том, что между синхронизированными статическими методами и синхронизованными нестационарными методами отсутствует связь, т.е.

class A {
    static synchronized f() {...}
    synchronized g() {...}
}

Main:

A a = new A();

Тема 1:

A.f();

Тема 2:

a.g();

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

Ответ 4

Если вы не реализуете g() следующим образом:

g() {
    synchronized(getClass()) {
        ...
    }
}

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

Ответ 5

Посмотрите на страницу документации оракула на Внутренние блокировки и синхронизация

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

Ответ 6

Ниже примеры дают большую ясность между блокировкой объектов и объектов, надеюсь, что ниже пример поможет и другим :)

Например, мы имеем ниже методы: один приобретает класс и другую блокировку объекта:

public class MultiThread {

    public static synchronized void staticLock() throws InterruptedException {
        for (int i = 0; i < 10; i++) {
            Thread.sleep(100);
            System.out.println(Thread.currentThread().getName() + " " + i);
        }
    }

    public synchronized void objLock() throws InterruptedException {
        for (int i = 0; i < 10; i++) {
            Thread.sleep(100);
            System.out.println(Thread.currentThread().getName() + " " + i);
        }
    }
}

Итак, теперь у нас могут быть следующие сценарии:

  1. Когда потоки, использующие один и тот же объект, пытаются одновременно получить доступ к objLock или staticLock (т.е. оба потока пытаются получить доступ к одному и тому же методу)

    Thread-0 0
    Thread-0 1
    Thread-0 2
    Thread-0 3
    Thread-0 4
    Thread-1 0
    Thread-1 1
    Thread-1 2
    Thread-1 3
    Thread-1 4
    
  2. Когда потоки, использующие один и тот же объект, пытаются staticLock objLock методам staticLock и objLock (пытается получить доступ к различным методам)

    Thread-0 0
    Thread-1 0
    Thread-0 1
    Thread-1 1
    Thread-0 2
    Thread-1 2
    Thread-1 3
    Thread-0 3
    Thread-0 4
    Thread-1 4
    
  3. Когда потоки, использующие другой объект, пытаются получить доступ staticLock методу staticLock

    Thread-0 0
    Thread-0 1
    Thread-0 2
    Thread-0 3
    Thread-0 4
    Thread-1 0
    Thread-1 1
    Thread-1 2
    Thread-1 3
    Thread-1 4
    
  4. Когда потоки, использующие другой объект, пытаются получить доступ objLock методу objLock

    Thread-0 0
    Thread-1 0
    Thread-0 1
    Thread-1 1
    Thread-0 2
    Thread-1 2
    Thread-1 3
    Thread-0 3
    Thread-0 4
    Thread-1 4
    

Ответ 7

Статический метод также имеет связанный объект. Он принадлежит к файлу Class.class в наборе инструментов JDK. Когда файл .class загружается в плунжер, Class.class создает экземпляр его, называемый объектом шаблона.

Например: при попытке создать объект из существующего класса клиента, например

Customer c = new Customer();

Загрузка Customer.class в оперативную память. В этот момент Class.class в наборе инструментов JDK создает объект, называемый объектом Template, и загружает этот объект Customer.class в этот объект шаблона. Статические члены этого класса Customer.class становятся атрибутами и методами в этом объекте шаблона.

Таким образом, статический метод или атрибут также имеет объект

Ответ 8

Для тех, кто не знаком статический синхронизированный метод, заблокированный в объекте класса, например. для класса string его String.class, в то время как синхронизированный метод блокирует метод для текущего экземпляра объекта, обозначенного ключевым словом "this" в Java. Поскольку оба этих объекта различны, у них есть разные блокировки, поэтому, когда один поток выполняет статический синхронизированный метод, другой поток в java не должен ждать, пока этот поток вернется, вместо этого он получит отдельный замок, обозначенный байтом .class literal и войдет в статическую синхронизацию метод.