Watki, semafory

0

Mam taki problemik. W zasadzie wrzucam działający kod, ale chciałbym dowiedzieć się co o tym myślicie.
Problem jest taki, że mamy jakiś (ograniczony jak dodamy konsumentow, na razie tylko producenci) bufor, dajmy na to jakąś prostą kolejke zaimplementowaną na tablicy (push get isempty isfull) i teraz jak gdzies w producencie chce cos wrzucic do kolejki to:(takich producentow jest np 8)

semafor.aquire();
koleka.robCos();
semafor.release();

i teraz przechodzimy do implementacji klasy MySemaphore. Chce miec pewnosc ze zasob(na razie semafor binarny) zostanie przydzielony watkowi ktory czeka najdluzej.

public class MySemaphore {

int counter;
private LinkedList<Thread> waitingThreads;
private LinkedList<Thread> currentThreads;

public MySemaphore(int n){
    counter = n;
    waitingThreads = new LinkedList<Thread>();
    currentThreads = new LinkedList<Thread>();
}

public void acquire() throws InterruptedException{
    synchronized(this){
        waitingThreads.addLast(Thread.currentThread());
        while (counter==0 || !waitingThreads.peek().equals(Thread.currentThread())){
            this.notifyAll();

// ta linijka powyzej nie daje mi spokoju. Co myslicie o czyms takim? (notiify i zaraz potem wait)

            this.wait();
        }
        counter--;
        Thread t = waitingThreads.pollFirst();
        currentThreads.add(t);

    }

}

public void release(){
    synchronized(this){
        if(currentThreads.remove(Thread.currentThread())){
            //zeby zwolnic semafor trzeba go miec
            counter++;
        }else{
            waitingThreads.remove(Thread.currentThread());
        }
        this.notifyAll();
    }
}

}

Moje rozwiazanie opiera sie na 2 kolejkach - jedna zawiera watki ktore pracuja na zosobie, druga kolejke oczekujacych. w Petli while (counter==0 || !waitingThreads.peek().equals(Thread.currentThread())) musze wybudzic wszystkich oczekujacych na zasob zeby miec pewnosc ze wybudze 1 w kolejce watek (w waitingThreads). Czy ma ktoś moze inny pomysl, jak zapewnic by watki po kolei dostawaly zasob, a jednoczesnie zeby pilnowac czy ktos nie chce oddac praw do zasobu nie posiadajac ich?

0

Użyj standardowej klasy semaforu.
Jednego dla konsumentów i drugiego dla producentów.

Jeżeli chcesz mieć pewność, że procesy zostaną dopuszczone według FIFO, to ustaw w konstrukorze "fair" na true.

http://java.sun.com/javase/6/[...]Semaphore%28int,%20boolean%29

Semaphore dlaKonsumentow = new Semaphore(0, true);
Semaphore dlaProducentow = new Semaphore(WIELKOSC_BUFORA, true);

Konsument musi w pętli robić tak:
dlaKonsumentow.acquire()
//pobranie zasobu
dlaProducentow.release()
//konsumpcja

Producent:
//produkcja
dlaProducentow.acquire()
//wstawienie zasobu
dlaKonsumentow.release()

Oczywiście operacje pobrania i wstawienia elementów muszą być w sekcji krytycznej, np. aby dwóch producentów nie wstawiało elementu jednocześnie.

1 użytkowników online, w tym zalogowanych: 0, gości: 1, botów: 0