Реализация очереди в семафоре

 
 
 
Сообщения:13
Всем добрый день!

В рамках учебы - необходимо реализовать 1-ю задачу о читателях-писателях на семафорах:
Пока память открыта на чтение, давать читателям беспрепятственный доступ. Писатели могут ждать сколько угодно.
Необходимо эмулировать доступ к базе данных и ограничить чтение\запись с использованием собственно-написанного семафора.
Множество потоков пытается одновременно читать и писать.

Вопрос:
Как можно реализовать очередь FIFO в семафоре и верно ли реализован он сам?

public class MySemaphore { 

    private volatile int permits;

    public MySemaphore(int permits) {
        this.permits = permits;
    }
    
    public synchronized void acquire(int n) {
        while (this.permits < n) 
        {
            try {
                this.wait();
            } catch (InterruptedException e) {
                System.out.println("Error: " + e.getMessage());
                Thread.currentThread().interrupt();
            }
        }
        this.permits -= n;
    }

    public synchronized void release(int n) {
        this.permits += n;
        this.notify();
    }
Изменен:02 дек 2018 19:51
 
 
Сообщения:762
В acquire не надо перехватывать InterruptedException. Вы же не знаете, зачем его инициировали и как не него реагировать.
В release надо вызывать notifyAll() вместо notify() - ведь не исключено, что освобождающихся пермитов хватит на несколько ожидающих потоков.

А в остальном все нормально.
Изменен:03 дек 2018 15:39
 
 
Сообщения:9745
Я че-т не понимаю где здесь семафор и где очередь. Что такое "n" в acquire() & release()? И не понятно как будет обеспечиваться FIFO если в коде нет ничего что бы указывало кто пришел в каком порядке.
Изменен:03 дек 2018 18:32
 
 
Сообщения:13
Quote:
В acquire не надо перехватывать InterruptedException. Вы же не знаете, зачем его инициировали и как не него реагировать.

Спасибо, сделать throws?
Quote:
В release надо вызывать notifyAll() вместо notify() - ведь не исключено, что освобождающихся пермитов хватит на несколько ожидающих потоков.

Спасибо, получается будем всех - и они уже "сами разберутся сколько им освободили пермитов"?
Quote:
Я че-т не понимаю где здесь семафор и где очередь. Что такое "n" в acquire() & release()?

n - число разрешений для семафора
Quote:
И не понятно как будет обеспечиваться FIFO если в коде нет ничего что бы указывало кто пришел в каком порядке.

В этом то и вопрос)?
Получается необходимо сделать (я так думаю...) внутри семафора обычную очередь из Object'ов, в которой на каждом эл-те вызывать wait() только для одного потока, а в release() делать notify() для первого стоящего...но как это красиво и правильно реализовать, это вопрос?
 
 
Сообщения:762
Evening:
Спасибо, сделать throws?
Да
Evening:
Quote:
И не понятно как будет обеспечиваться FIFO если в коде нет ничего что бы указывало кто пришел в каком порядке.
В этом то и вопрос)? Получается необходимо сделать (я так думаю...) внутри семафора обычную очередь из Object'ов, в которой на каждом эл-те вызывать wait() только для одного потока, а в release() делать notify() для первого стоящего...но как это красиво и правильно реализовать, это вопрос?
В стандартном явовском семафоре можно при создании задать параметр fair - то есть, будут пермиты раздаваться строго по очереди или кому попало. То есть, оба варианта имеют смысл.
Я бы не стал создавать новые объекты для поддержания строгого порядка, а сделал бы "по советски" - если потоку не досталось пермитов, он запоминает ("рисует себе на руке") свой номер в очереди, и потом уходит на wait(). Вернувшись, он проверяет, не настала ли его очередь. Для этого в семафоре достаточно завести 2 переменные типа long - первый свободный номер и номер того, чья очередь наступила.
 
 
Сообщения:13
Спасибо за помощь!
 
Модераторы:Нет
Сейчас эту тему просматривают:Нет