Семафоры в Java - PullRequest
       4

Семафоры в Java

1 голос
/ 03 марта 2011

Кто-нибудь знает, как реализовать элементарный семафор в Java без использования wait(), notify() или synchronize. Я не ищу решения этой проблемы, просто указатель в правильном направлении, потому что Я полностью потерян на этом.

Ответы [ 5 ]

2 голосов
/ 03 марта 2011
1 голос
/ 03 марта 2011

У меня была похожая домашняя работа несколько лет назад в моем университете, но на C ++. Java - это язык слишком высокого уровня для такого рода вещей.

Вот моя реализация сигнала и ожидания в C ++, но я не знаю, будет ли это полезно, потому что вам придется реализовать много других вещей.

int KernelSem::wait() {
    lock();
    if(--value < 0) {
        PCB::running->state = PCB::BLOCKED;
        PCB::running->waitingAtSem = this;
        blockedQueue->put(PCB::running);
        dispatch();
    }
    else {
        PCB::running->deblockedBy = 0;
        if(semPreempt) dispatch();
    }
    unlock();
    return PCB::running->deblockedBy;
}


void KernelSem::signal() {
    lock();
    if(value++ < 0) {
        PCB* tempPCB = blockedQueue->get();
        if(tempPCB) {
            tempPCB->state = PCB::READY;
            tempPCB->deblockedBy = 0;
            tempPCB->waitingAtSem = 0;
            Scheduler::put(tempPCB);
        }
    }
    if(semPreempt) dispatch();
    unlock();
}

Функции блокировки и разблокировки: asm{cli} и asm{sti} (сбросить / установить флаг прерывания). PCB представляет собой блок управления процессом .

Надеюсь, это поможет

0 голосов
/ 26 мая 2014

Выполнение, как предлагается в принятом ответе, приведет к множеству одновременных проблем, поскольку вы не можете гарантировать взаимное исключение с этим. Например, два потока, запрашивающие увеличение целого числа, оба одновременно будут считать логическое значение (которое предлагается в качестве блокировки), тогда оба будут думать, что все в порядке, и затем оба установят в bool противоположное значение. Оба потока будут вносить изменения, и когда они это сделают, они оба запишут значение в (не) взаимоисключающую переменную, и вся цель семафора будет потеряна. Метод wait () предназначен для ожидания, пока что-то не произойдет, и это именно то, что вы хотите сделать.

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

(Конечно, семафоры - это именно то, что вы хотите сделать, но поскольку они используют ожидание, я предположил, что вы хотели что-то, что вообще не использует ожидание ...)

0 голосов
/ 03 марта 2011

очень простым простым (опять же) простым способом вы можете реализовать это с помощью простого int или логического значения.

Проверьте int или логическое значение перед разрешением доступа. Если это 0 (надоело логическое значение), добавьте 1 и продолжайте. Если нет, выполните Thread.yield () и попробуйте еще раз. Когда вы отпустите, удалите 1 из int и продолжите.

Наивная реализация, но отлично работает.

0 голосов
/ 03 марта 2011

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

...