Ответ 1
Поскольку у статического метода нет связанного объекта, будет ли синхронизированная блокировка ключевого слова для класса вместо объекта?
Да.:)
В учебниках Java говорится: "Невозможно чередование двух вызовов синхронизированных методов на одном объекте".
Что это значит для static method
? Поскольку у статического метода нет связанного объекта, будет ли синхронизированная блокировка ключевого слова для класса вместо объекта?
Поскольку у статического метода нет связанного объекта, будет ли синхронизированная блокировка ключевого слова для класса вместо объекта?
Да.:)
Просто добавьте немного подробностей в Оскар (приятный лаконичный!) ответ, соответствующий раздел по Спецификации Java Language 8.4.3.6, 'synchronized Methods':
Синхронизированный метод получает монитор (§17.1) перед его выполнением. Для класса (статического) метода используется монитор, связанный с объектом класса для класса метода. Для метода экземпляра используется связанный с ним монитор (объект, для которого был вызван метод).
Один момент, о котором вы должны быть осторожны (несколько программистов, как правило, попадают в эту ловушку), заключается в том, что между синхронизированными статическими методами и синхронизованными нестационарными методами отсутствует связь, т.е.
class A {
static synchronized f() {...}
synchronized g() {...}
}
Main:
A a = new A();
Тема 1:
A.f();
Тема 2:
a.g();
f() и g() не синхронизированы друг с другом и, таким образом, могут выполняться полностью одновременно.
Если вы не реализуете g() следующим образом:
g() {
synchronized(getClass()) {
...
}
}
Я нахожу этот шаблон полезным также, когда я хочу реализовать взаимное исключение между разными экземплярами объекта (что необходимо, например, при подключении внешнего ресурса).
Посмотрите на страницу документации оракула на Внутренние блокировки и синхронизация
Вы можете задаться вопросом, что происходит, когда вызывается статический синхронизированный метод, поскольку статический метод связан с классом, а не с объектом. В этом случае поток получает встроенный замок для объекта Class, связанного с классом. Таким образом, доступ к статическим полям класса управляется блокировкой, отличной от блокировки для любого экземпляра класса.
Ниже примеры дают большую ясность между блокировкой объектов и объектов, надеюсь, что ниже пример поможет и другим :)
Например, мы имеем ниже методы: один приобретает класс и другую блокировку объекта:
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);
}
}
}
Итак, теперь у нас могут быть следующие сценарии:
Когда потоки, использующие один и тот же объект, пытаются одновременно получить доступ к 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
Когда потоки, использующие один и тот же объект, пытаются 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
Когда потоки, использующие другой объект, пытаются получить доступ 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
Когда потоки, использующие другой объект, пытаются получить доступ 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
Статический метод также имеет связанный объект. Он принадлежит к файлу Class.class в наборе инструментов JDK. Когда файл .class загружается в плунжер, Class.class создает экземпляр его, называемый объектом шаблона.
Например: при попытке создать объект из существующего класса клиента, например
Customer c = new Customer();
Загрузка Customer.class в оперативную память. В этот момент Class.class в наборе инструментов JDK создает объект, называемый объектом Template, и загружает этот объект Customer.class в этот объект шаблона. Статические члены этого класса Customer.class становятся атрибутами и методами в этом объекте шаблона.
Таким образом, статический метод или атрибут также имеет объект
Для тех, кто не знаком статический синхронизированный метод, заблокированный в объекте класса, например. для класса string его String.class, в то время как синхронизированный метод блокирует метод для текущего экземпляра объекта, обозначенного ключевым словом "this" в Java. Поскольку оба этих объекта различны, у них есть разные блокировки, поэтому, когда один поток выполняет статический синхронизированный метод, другой поток в java не должен ждать, пока этот поток вернется, вместо этого он получит отдельный замок, обозначенный байтом .class literal и войдет в статическую синхронизацию метод.