1

Для моего приложения я должен быть уверен, что в критический сеанс обрабатывается только один тип потока. Количество потоков для данного типа не указано и может быть «большим». Я пришел с простым решением:Три типа потоков, пытающихся получить доступ к критическому разделу

MutableInt a,b,c; 
Semaphore mutex; 

void enterA() { 
    while (true) { 
     mutex.acquire(); 
     if (b.intValue() == 0 && c.intValue() == 0) { 
      a.increase(); 
      break; 
     } 
     mutex.release(); 
    } 
} 

void exitA() { 
    while(true) { 
     mutex.acquire(); 
     a.decrease(); 
     mutex.release(); 
    } 
} 

Я пропуск обработки исключений и B & C часть вызвать его просто копипаст.

Работает так, как ожидалось (возможность голодания голосом в порядке), но сгенерированная нагрузка слишком велика. Нитки постоянно проверяют счетчики. Я чувствую, что есть другое решение, но не могу придумать ни одного примера.

+0

Причина высокой загрузки процессора заключается в том, что один поток всегда может работать. В вашем коде нет блокирующих вызовов, кроме mutex.acquire(). Поэтому я полагаю, что одно ядро ​​ЦП постоянно находится на 100%. – tbsalling

+0

Thx для обобщения, однако этот, я действительно знаю. Я пытаюсь выяснить способ уведомления только тех потоков, которые заинтересованы в событии. – yusuf

ответ

1

Я не могу определить, является ли ваше решение частью проблемы, но в ее нынешнем виде я бы рекомендовал переместиться на AtomicInteger, который обрабатывает все инкремент и т. Д. Для вас без блокировки.

Если это сложнее, вам следует рассмотреть возможность использования AtomicReference с некоторым классом аккумулятора и использовать метод compareAndSet(...) для его атомарного обновления.

Например, вы могли бы хранить 3 целых числа в MutableInts классе и сделать что-то вроде следующего:

final AtomicReference<MutableInts> reference = 
    new AtomicReference<MutableInts>(new MutableInts(0, 0, 0)); 
... 
do { 
    MutableInts ints = reference.get(); 
    // increment the ints properly which should generate a new MutableInts class 
    // it should _not_ make changes to `ints` itself 
    MutableInts newInts = ints.mutateSomehow(...); 
    // this spins in case some other thread updated it before us here 
} while (!reference.compareAndSet(ints, newInts)); 

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

  • Каждый поток обновляет свои собственные данные, а затем каждый раз так часто (или, может быть, только в конце обработки) синхронизируется с центральными счетчиками. Такие же замки, но делают это лот реже.
  • Каждый поток может обновлять потоки volatile счетчиков, а поток опроса может считывать счетчики и обновлять центральную информацию. Не уверен, разрешено ли volatile.
+0

К сожалению, меня заставили использовать простые семафоры. На самом деле MutableInt - это просто ярлык для вопросов и ответов, чтобы минимизировать сложность кода ... - этот класс написан сам – yusuf

+0

Итак, это домашнее задание @yusuf? – Gray

+0

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