Будут ли конфликтовать блокировки классов и блокировки объектов? Будут ли конфликтовать блокировки объектов и частные блокировки? Иллюстрация через примеры.
1. Соответствующие соглашения
Чтобы прояснить следующее описание, мы сначала сделаем следующие соглашения относительно соответствующих определений блокировок, рассматриваемых в этой статье:
1. Блокировка класса. Добавьте статические и синхронизированные блокировки к методам в коде или синхронизированным (xxx.class) сегментам кода, например, increament() ниже;
2. Блокировка объекта. Добавьте синхронизированную блокировку к методу в коде или синхронизированному (this) сегменту кода, например, SynOnMethod() и SynInMethod() ниже;
3. Частная блокировка: объявите частное свойство, такое как частная блокировка объекта, внутри класса и синхронизируйте (заблокируйте) сегмент кода, который необходимо заблокировать, например, SynMethodWithObj() ниже.
2. Тестовый код
1. Напишите стартовый класс ObjectLock.
Скопируйте код кода следующим образом:
общественный класс ObjectLock {
public static void main(String[] args) {
System.out.println("время начала = " + System.currentTimeMillis()+"мс");
Тест LockTestClass = новый LockTestClass();
для (int я = 0; я <3; я++) {
Поток потока = новый ObjThread (тест, я);
поток.start();
}
}
}
2. Напишите класс потока ObjThread для запуска метода синхронизации (обратите внимание, что его метод запуска может быть настроен для разных тестов).
Скопируйте код кода следующим образом:
общественный класс ObjThread расширяет поток {
Блокировка LockTestClass;
интервал я = 0;
public ObjThread (блокировка LockTestClass, int i) {
this.lock = блокировка;
это.я = я;
}
общественный недействительный запуск () {
//Блокируемый метод
//lock.noSynMethod(this.getId(),this);
//Метод блокировки объекта 1, с использованием синхронизированного SynInMethod
lock.synInMethod();
//Метод блокировки объекта 2, с использованием метода Synchronized(this)
//lock.synOnMethod();
//Метод приватной блокировки с использованием метода Synchronized(object)
//lock.synMethodWithObj();
//Метод блокировки класса с использованием статического метода синхронизированного приращения
LockTestClass.increment();
}
}
3. Напишите еще один класс проверки блокировки LockTestClass, включая различные методы блокировки.
Скопируйте код кода следующим образом:
общественный класс LockTestClass {
//Используется для подсчета блокировок классов
частный статический int я = 0;
//Частный замок
частный объект объекта = новый объект ();
/**
* <р>
* Безблокировочный метод
*
* @param идентификатор потока
* Тема @param
*/
public void noSynMethod (long threadID, поток ObjThread) {
System.out.println("nosyn: class obj равен " + thread + ", threadId равен"
+ идентификатор потока);
}
/**
* Метод блокировки объекта 1
*/
публичная синхронизированная недействительность SynOnMethod() {
System.out.println("synOnMethod начинается" + ", time = "
+ System.currentTimeMillis() + «мс»);
пытаться {
Thread.sleep(2000L);
} catch (InterruptedException e) {
е.printStackTrace();
}
System.out.println("synOnMethod заканчивается");
}
/**
* Метод блокировки объектов 2, используйте синхронизированный (это) для блокировки
*/
общественный недействительный SynInMethod () {
синхронизировано (это) {
System.out.println("synInMethod начинается" + ", time = "
+ System.currentTimeMillis() + «мс»);
пытаться {
Thread.sleep(2000L);
} catch (InterruptedException e) {
е.printStackTrace();
}
System.out.println("synInMethod заканчивается");
}
}
/**
* Способ блокировки объектов 3
*/
общественный недействительный SynMethodWithObj () {
синхронизированный (объект) {
System.out.println("synMethodWithObj начинается" + ", time = "
+ System.currentTimeMillis() + «мс»);
пытаться {
Thread.sleep(2000L);
} catch (InterruptedException e) {
е.printStackTrace();
}
System.out.println("synMethodWithObj заканчивается");
}
}
/**
* Блокировка класса
*/
общедоступная статическая синхронизированная недействительная инкрементация () {
System.out.println("класс синхронизирован. i = " + i + ", time = "
+ System.currentTimeMillis() + «мс»);
я++;
пытаться {
Thread.sleep(2000L);
} catch (InterruptedException e) {
е.printStackTrace();
}
System.out.println("Синхронизация классов заканчивается.");
}
}
3. Результаты испытаний
1. Чтобы протестировать блокировки классов и объектов, измените метод run ObjectThread следующим образом:
Скопируйте код кода следующим образом:
общественный недействительный запуск () {
//Блокируемый метод
//lock.noSynMethod(this.getId(),this);
//Метод блокировки объекта 1, с использованием синхронизированного SynInMethod
lock.synInMethod();
//Метод блокировки объекта 2, с использованием метода Synchronized(this)
//lock.synOnMethod();
//Метод приватной блокировки с использованием метода Synchronized(object)
//lock.synMethodWithObj();
//Метод блокировки класса с использованием статического метода синхронизированного приращения
LockTestClass.increament();
}
Выход терминала:
Скопируйте код кода следующим образом:
время начала = 1413101360231мс
SynInMethod начинается, время = 1413101360233мс
SynInMethod заканчивается
класс синхронизирован я = 0, время = 1413101362233мс.
SynInMethod начинается, время = 1413101362233мс
синхронизация классов заканчивается.
SynInMethod заканчивается
класс синхронизирован я = 1, время = 1413101364233мс.
SynInMethod начинается, время = 1413101364233мс
синхронизация классов заканчивается.
SynInMethod заканчивается
класс синхронизирован я = 2, время = 1413101366234мс.
синхронизация классов заканчивается.
Вы можете видеть, что метод блокировки объекта (synInMothod) при первом запуске работает на 2 секунды быстрее, чем метод блокировки класса (increment). Это связано с тем, что при выполнении synInMehtod он приостанавливается на 2 секунды, а затем выполняет увеличение, и эти два. методы используют один и тот же поток. Таким образом, если increment помещается перед SynInMethod в run, то при первом запуске приращение будет на 2 секунды быстрее.
Когда запускается метод блокировки класса, метод блокировки объекта другого потока также запускается почти одновременно, что указывает на то, что эти два потока не используют одну и ту же блокировку и конкуренции не будет.
Вывод: блокировки классов и блокировки объектов не будут конкурировать, и их методы блокировки не будут влиять друг на друга.
2. Приватные блокировки и блокировки объектов. Метод run ObjectThread изменяется следующим образом:
Скопируйте код кода следующим образом:
общественный недействительный запуск () {
//Блокируемый метод
//lock.noSynMethod(this.getId(),this);
//Метод блокировки объекта 1, с использованием синхронизированного SynInMethod
lock.synInMethod();
//Метод блокировки объекта 2, с использованием метода Synchronized(this)
//lock.synOnMethod();
//Метод приватной блокировки с использованием метода Synchronized(object)
lock.synMethodWithObj();
//Метод блокировки класса с использованием статического метода синхронизированного приращения
//LockTestClass.increament();
}
Выход терминала:
Скопируйте код кода следующим образом:
время начала = 1413121912406мс
SynInMethod начинается, время = 1413121912407мс.
SynInMethod завершается.
SynMethodWithObj начинается, время = 1413121914407мс
SynInMethod начинается, время = 1413121914407мс.
SynInMethod завершается.
SynMethodWithObj заканчивается
SynInMethod начинается, время = 1413121916407мс.
SynMethodWithObj начинается, время = 1413121916407мс
SynInMethod завершается.
SynMethodWithObj заканчивается
SynMethodWithObj начинается, время = 1413121918407мс
SynMethodWithObj заканчивается
Очень похоже на блокировки классов и блокировки объектов.
Вывод: частные блокировки и блокировки объектов не будут конкурировать, и их методы блокировки не будут влиять друг на друга.
3.Synchronized добавляется непосредственно в метод и Synchronized(this), а метод run ObjectThread изменяется следующим образом:
Скопируйте код кода следующим образом:
общественный недействительный запуск () {
//Блокируемый метод
//lock.noSynMethod(this.getId(),this);
//Метод блокировки объекта 1, с использованием синхронизированного SynInMethod
lock.synInMethod();
//Метод блокировки объекта 2, с использованием метода Synchronized(this)
lock.synOnMethod();
//Метод приватной блокировки с использованием метода Synchronized(object)
//lock.synMethodWithObj();
//Метод блокировки класса с использованием статического метода синхронизированного приращения
//LockTestClass.increament();
}
Выход терминала:
Скопируйте код кода следующим образом:
время начала = 1413102913278мс
SynInMethod начинается, время = 1413102913279мс
SynInMethod заканчивается
SynInMethod начинается, время = 1413102915279мс
SynInMethod заканчивается
SynOnMethod начинается, время = 1413102917279мс
SynOnMethod заканчивается
SynInMethod начинается, время = 1413102919279мс
SynInMethod заканчивается
SynOnMethod начинается, время = 1413102921279мс
SynOnMethod заканчивается
SynOnMethod начинается, время = 1413102923279мс
SynOnMethod заканчивается
Как вы можете видеть, оба вывода выводятся строго последовательно (конечно, не определяется, запускается ли сначала SynInMethod или SynOnMethod при повторном выполнении, в зависимости от того, кто получает блокировку).
Вывод: синхронизированный метод, добавленный непосредственно к методу, и синхронизированный(это) оба блокируют текущий объект. Два метода блокировки находятся в конкурирующих отношениях, и одновременно может выполняться только один метод.