2013-12-02 2 views
0

Вопрос 1:Тупик в семафор функции

Я читал в Hard-core Multi-threading in Java и не ударяться в семафора примере ниже.

package com.dswgroup.conferences.borcon.threading; 

public class ResourceGovernor { 
    private int count; 
    private int max; 

    public ResourceGovernor(int max) { 
     count = 0; 
     this.max = max; 
    } 

    public synchronized void getResource(int numberof) { 
     while (true) { 
      if ((count + numberof) <= max) { 
       count += numberof; 
       break; 
      } 
      try { 
       wait(); 
      } catch (Exception ignored) {} 
     } 
    } 

    public synchronized void freeResource(int numberof) { 
     count -= numberof; 
     notifyAll(); 
    } 
} 

Я чувствую, что это может привести к тупиковой ситуации в следующей ситуации: используются

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

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

Но могу ли я уверенно сказать, что я правильно поставил диагноз 1-й проблемы. (Нужно перепроверить, так как его опубликовал в течение длительного времени на embarcadero.com)

Вопрос 2:

Могу ли я смело утверждать, что семафор только один ресурс имеет такое же поведение, как блокировка мьютекса?

+1

Важная информация, которую вы упомянули, может быть преднамеренным. Например, в классе Семафора JDK говорится: «Нет требования, чтобы поток, который выдавал разрешение, должен был получить это разрешение, вызвав его». Совершенно законно создавать Семафор без каких-либо разрешений, один поток пытается получить разрешение, а затем еще один поток «освобождает» разрешение (никогда не приобретавшее его в первую очередь). Таким образом, семафор также может имитировать CountDownLatch (подобно тому, как бинарный семафор - 1 разрешить - может имитировать мьютекс). – yshavit

+0

Имейте в виду, что статья с 2004 года. Все ее содержание устарело сегодня. Для лучшего решения взгляните на параллельный пакет. – TwoThe

ответ

5

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

Вы пропустили тот факт, что вызов wait() слагает монитор, поэтому другой синхронизируется код является в состоянии выполнить. Из документов для wait():

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

Для вашего второго вопроса:

Могу ли я с уверенностью сказать, что семафор только один ресурс имеет такое же поведение, как блокировка мьютекса?

Я подозреваю, что, хотя реализация, которую вы показали, фактически не останавливает вас от звонка freeResource несколько раз. Это немного странная реализация в том, что я обычно вижу семафоры, подсчитывающие количество ресурсов , оставшихся, а не количество ресурсов принято - хотя они эквивалентны, конечно.

1

Вопрос 2: Да, он похож на мьютекс. Но хотя мьютексы и семафоры имеют сходство в их реализации, их всегда следует использовать по-разному. Nice Explanation Here

+0

спасибо @rookieB. +1 для ссылки –

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