2016-01-29 2 views
1

В Java, если несколько потоков ожидают() одно и то же условие A, тогда другой поток вызывает signalAll() при условииA, будут ли все очереди, ожидающие состояния, разблокироваться одновременно?В Java, будет ли несколько потоков ждать() одно и то же условие разблокируется в одно и то же время позже?

К примеру, у меня есть надстройка и способ удалить из очереди:

public void add(E newValue) throws InterruptedException 
{ 
    queueLock.lock(); 
    try 
    { 
     while (size == elements.length) 
      spaceAvailableCondition.await(); 
     elements[tail] = newValue; 
     tail++; 
     size++; 
     if (tail == elements.length) 
      tail = 0; 
     valueAvailableCondition.signalAll(); 
    } 
    finally 
    { 
     queueLock.unlock(); 
    } 
} 

public E remove() throws InterruptedException 
{ 
    queueLock.lock(); 
    try 
    { 
     while (size == 0) 
      valueAvailableCondition.await(); 
     E r = (E) elements[head]; 
     head++; 
     size--; 
     if (head == elements.length) 
      head = 0; 
     spaceAvailableCondition.signalAll(); 
     return r; 
    } 
    finally 
    { 
     queueLock.unlock(); 
    } 
} 

Пусть нескольких потоков держать вызов добавить метод в общую очереди. Через некоторое время очередь заполнена. Все эти потоки застревают в spaceAvailableCondition.awati(). Затем у меня есть этот поток, который вызывает метод remove, signalAll()spaceAvailableCondition. Будут ли все потоки, которые вызывают add, разблокировать и запустить метод, что приведет к повреждению в этой очереди?

Я задаю этот вопрос, потому что я думаю, что все другие «добавления потоков» внедрили queueLock.lock(). Тогда вся нить имеет право владения этим замком.

+0

Почему вы не попробуете его с помощью простой печати? – Bifz

+1

@Bifz Потому что «дать ему попробовать» не подходит для рассуждений о параллелизме. – chrylis

+0

Если вы поместили печать сразу после ожидания и сигнала вызова один раз, вы должны увидеть, сколько раз просыпалось. – Bifz

ответ

1

Не уверен, что я правильно понимаю ваш вопрос.

Хотя await Ing потоки будут разбужены signalAll(), но только один из них может повторно получить блокировку (я предполагаю, что это queueLock), связанный с spaceAvailableCondition те нити, ожидающие в. Следовательно, только 1 поток «добавить» будет выполнять логику.

+0

И тот, кто повторно приобретает замок, является тем, у кого есть приоритет _hieghst. – jfun

+0

Я не могу вспомнить из своей памяти, что приоритет потока имеет какое-либо отношение к порядку пробуждения (следовательно, он может получить блокировку). Я считаю, что это реализация-depedent –

0

Предполагая, что spaceAvailableCondition является переменной условий, которая была получена от queueLock, то нет, они не будут просыпаться «одновременно».

Вы уже знаете, что вам не позволено звонить spaceAvailableCondition() из потока, который не имеет queueLock заблокирован. Это потому, что, то spaceAvailableCondition.await() вызов делает эти вещи:

  1. Он освобождает queueLock.

  2. Он ожидает другого потока, чтобы сигнализировать состояние,

  3. Он вновь приобретает queueLock

  4. Он возвращается.

только один поток может владеть queueLock в то время, поэтому, когда состояние сигнализируется, только один поток будет иметь возможность немедленно вернуться из await() вызова. Следующий поток не сможет получить блокировку и вернуться с await() до тех пор, пока первый не освободит замок и т. Д.

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