Если я синхронизировал два метода в одном classе, они могут работать одновременно?

Если я синхронизировал два метода в одном classе, могут ли они работать одновременно на одном и том же объекте ? например:

class A { public synchronized void methodA() { //method A } public synchronized void methodB() { // method B } } 

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

Но могу ли я запустить methodB() для разных streamов, пока methodA() все еще запущен? (тот же объект)

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

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

 class A { private final Object lockA = new Object(); private final Object lockB = new Object(); public void methodA() { synchronized(lockA) { //method A } } public void methodB() { synchronized(lockB) { //method B } } } 

Java Thread получает блокировку уровня объекта, когда он входит в синхронный Java-метод экземпляра и получает блокировку уровня classа, когда он входит в статический синхронизированный Java-метод.

В вашем случае методы (экземпляр) имеют один и тот же class. Поэтому, когда stream вступает в java-синхронизированный метод или блокирует его, получает блокировку (объект, на который вызывается метод). Таким образом, другой метод нельзя вызывать одновременно на одном и том же объекте до тех пор, пока первый метод не будет завершен и не будет заблокирован (по объекту).

В вашем случае вы синхронизировали два метода в одном экземпляре classа. Таким образом, эти два метода не могут выполняться одновременно в разных streamах одного и того же экземпляра classа A. Но они могут выполняться в разных экземплярах classа A.

 class A { public synchronized void methodA() { //method A } } 

такой же как:

 class A { public void methodA() { synchronized(this){ // code of method A } } } 

Из ссылки документации oracle

Синхронизация методов синхронизации имеет два эффекта:

Во-первых, невозможно, чтобы две вызовы синхронизированных методов на одном объекте чередовали. Когда один stream выполняет синхронизированный метод для объекта, все другие streamи, которые вызывают синхронизированные методы для одного и того же блока объектов (приостанавливают выполнение) до тех пор, пока первый stream не будет выполнен с объектом.

Во-вторых, когда синхронизированный метод завершается, он автоматически устанавливает связь между событиями и последующим вызовом синхронизированного метода для одного и того же объекта. Это гарантирует, что изменения состояния объекта будут видны для всех streamов

Это ответит на ваш вопрос: на том же объекте вы не можете вызвать второй синхронизированный метод, когда выполняется первое синхронизированное выполнение метода.

Посмотрите эту страницу документации, чтобы понять внутренние блокировки и поведение блокировки.

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

Подумайте о своем коде как о нижеследующем:

 class A { public void methodA() { synchronized(this){ //method A body } } public void methodB() { synchronized(this){ // method B body } } 

Таким образом, синхронизированный на уровне метода просто означает синхронизировать (это). если какой-либо stream выполняет метод этого classа, он должен получить блокировку перед началом выполнения и удерживать ее до завершения выполнения метода.

Но могу ли я запустить методB () для разных streamов, пока метод А () все еще запущен? (тот же объект)

Действительно, это невозможно!

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

Вы синхронизируете его на объекте, а не на classе. Поэтому они не могут одновременно работать на одном объекте

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

Interesting Posts

Как разрешить отказ доступа к собственному многопользовательскому программному обеспечению на подключенном или общем сетевом диске в Windows 7?

Как загрузить контакт Фото?

Передача объекта между компонентами @ViewScoped без использования параметров GET

AngularJS – привязка переключателей к моделям с булевыми значениями

Самый простой способ воспроизведения аудио RTMP-streamа в Android

Как установить строку внутри прямоугольника?

Как получить имена файлов, открытых процессом?

сообщение об ошибке отказано

MySQL Выберите дату, равную сегодняшнему

Плагин Java не работает в Chrome – как я могу это исправить?

Плагин Adobe Reader для браузера Firefox ворует прокрутку сенсорной панели

Play Framework 2.0 и ведение журнала Ebean SQL

Новые текстовые файлы создаются с заглавными расширениями

Как использовать TLS 1.2 в Java 6

Запуск приложений как администратора по умолчанию в Windows 10

Давайте будем гением компьютера.