2016-08-02 2 views
1

Я создал новый поток под названием ThreadA и начал это в основном потоке.Управление не возвращается к ожидающей нити после уведомления

Я ожидал, что некоторые операции будут завершены в ThreadA.

После некоторых операций я отправил уведомление с использованием notify.

Но код ниже wait в основном потоке не вызывается, он ждет завершения всего кода ThreadA.

Является ли это нитью или просто потоком, получающим доступ для запуска проблемы?

Job job = new MyJob(); 
job.schedule(); 
synchronized(job) { 
    job.wait(); 
    sysout("After notify"); 
} 

Здесь job является org.eclipse.core.runtime.jobs

Внутри Работы запустить метод:

run { 
    synchronized(this) { 
     step 1(); 
     notify(); 
     step 2(); 
    } 
} 

Здесь шаг 2 является большим кодом.

+2

Пожалуйста, покажите свой код (как именно вы вызываете 'wait' и' notify'). – yole

+0

Job job = new MyJob(); job.schedule(); синхронизированы (работа) {job.wait(); sysout («После уведомления»)} Здесь задание - org.eclipse.core.runtime.jobs. – user3302323

+0

Внутренний метод запуска работы: запустите {synchronized (this) {step 1(); поставить в известность(); step 2();}} Здесь шаг 2 - это большой код. – user3302323

ответ

1

Уведомляющий поток фактически не отправляет уведомление, пока оно не освободит блокировку. Вам нужно освободить блокировку до того, как уведомление может случиться, и ваш код этого не делает.

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

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

Ваш метод запуска работы удерживается на замке полностью от вызова шага 1 до вызова этапа2. Чтобы уведомленный поток ничего не делал об уведомлении, он должен прекратить ждать, что влечет за собой повторное приобретение блокировки, прежде чем он сможет выйти из метода wait (потому что он должен ввести свой собственный синхронизированный блок). Это означает, что нет никакого смысла отправлять уведомление до того, как уведомляющий поток освободит блокировку, потому что в любом случае ничто не может оживить поток нитей.

+0

Выполняет ли синхронизация (задание) блокировку на этом объекте? – user3302323

+0

@ user3302323 ключевое слово 'synchronize' обозначает блок, который может быть введен только одним потоком одновременно. Если другой поток в настоящее время находится в синхронизированном блоке на одном и том же объекте, выполнение приостанавливается до тех пор, пока другой поток не покинет свой синхронизированный блок. –

+0

Не могли бы вы подробно объяснить, как освободить и приобрести блокировки на объекте? – user3302323

Смежные вопросы