bariera n-wątkowa

0

Napisałem kod bariery dla trzech wątków:

public class Bariera {
    
    static Semafor arrive1 = new Semafor(0);
    static Semafor arrive2 = new Semafor(0);
    static Semafor arrive3 = new Semafor(0);
    
    public static void main(String[] args){
        new Worker1();
        new Worker2();
        new Worker3();
    }
    
    static class Worker1 implements Runnable{
        Worker1(){
            new Thread(this, "Worker1").start();
        }
        
        public void run(){
            try {
                arrive1.V();
                arrive1.V();
                arrive2.P();
                arrive3.P();
            } catch (InterruptedException ex) {}
            System.out.println("W1: przeszedlem bariere");
        }
    }
    
    static class Worker2 implements Runnable{
        Worker2(){
            new Thread(this, "Worker2").start();
        }
        
        public void run(){
            try {
                arrive2.V();
                arrive2.V();
                arrive1.P();
                arrive3.P();
            } catch (InterruptedException ex) {}
            System.out.println("W2: przeszedlem bariere");
        }
    }
    
    static class Worker3 implements Runnable{
        Worker3(){
            new Thread(this, "Worker3").start();
        }
        
        public void run(){
            try {
                arrive3.V();
                arrive3.V();
                arrive1.P();
                arrive2.P();
            } catch (InterruptedException ex) {}
            System.out.println("W3: przeszedlem bariere");
        }
    }
    
    static class Semafor{
        private int Sem;
        
        public Semafor (int ini){Sem = ini;}
        synchronized public void V(){
            ++Sem;
            notify();
        }
        synchronized public void P() throws InterruptedException{
            while (Sem==0) wait();
            --Sem;
        }
    }
 
}

Jednak chcę mieć kod uniwersalny na liczbę wątków, czyli n. Jakie zmiany proponujecie? Muszę stworzyć listę wątków i listę semaforów?
Nie chodzi o wzbogacenie programu o nowe elementy typu BlockingQueue, tylko uogólnienie mojego kodu dla n-wątków.

0

http://download.oracle.com/javase/1.5.0/docs/api/java/util/concurrent/CountDownLatch.html ?

Link jest zwiazany z tematem, ktory podales, bo nie chce mi sie czytac kodu. Byc moze nie o to Ci chodzi ;p Jesli nie, to napisz slowami, o co chodzi ;)

0

Poniekąd link jest związany z moim postem. Mnie jednak nie chodzi o stosowanie "gotowców" dostępnych w Javie (nie mogę :)), lecz o wykorzystanie mojej klasy Semafor. Czyli kod, który napisałem, wykorzystuje tę klasę, lecz sprowadza problem do trzech wątków. Nie mam za bardzo pomysłu jak obsłużyć n wątków, gdzie n oczywiście może być większe niż 3.

Czyli będzie jedna klasa Worker i lista wątków oraz lista semaforów?

0

Dobra, ale co masz realizować ? Taką barierę gromadzącą n wątków ? Czy co ? Może pomyśl o tablicy/wektorze semaforów i jakichś operacjach na nich ? Z resztą - nie wiem, co dokładnie chcesz zrobić, więc trudno mi doradzać.

0

Podano mi pseudokod dla bariery 3 wątkowej:

 //semafory licznikowe
semaphore arrive1=0, arrive2=0, arrive3=0;

process Worker1{
	V(arrive1)	//sygnalizuj przybycie partneroem
	V(arrive1)//sygnalizuj przybycie partneroem
	P(arrive2) //czekaj na drugi watek
	P(arrive3)//czekaj na trzeci watek
	...//przejscie bariery przez W1
}

process Worker2{
	V(arrive2)	//sygnalizuj przybycie partneroem
	V(arrive2)//sygnalizuj przybycie partneroem
	P(arrive1) //czekaj na pierwszy watek
	P(arrive3)//czekaj na trzeci watek
	...//przejscie bariery przez W2
}

process Worker3{
	V(arrive3)	//sygnalizuj przybycie partneroem
	V(arrive3)//sygnalizuj przybycie partneroem
	P(arrive1) //czekaj na pierwszy watek
	P(arrive2)//czekaj na drugi watek
	...//przejscie bariery przez W3
}

I kazano wykorzystać, tę klasę:

class Semafor{
        private int Sem;
        
        public Semafor (int ini){Sem = ini;}
        synchronized public void V(){
            ++Sem;
            notify();
        }
        synchronized public void P() throws InterruptedException{
            while (Sem==0) wait();
            --Sem;
        }
    } 

Z tym, że mam "ulepszyć" barierę. N wątków i później jakiś prosty przykładzik.

0

Ok, to proste. Tworzysz tablicę n semaforów (czyli od 0 do n-1). Każdy proces trzyma swój "numer identyfikacyjny" (od 0 do n-1). W momencie, gdy proces chce coś zrobić (przejść tę barierę), to wywołuje w pętli for n-1 razy (tak wynika z przykładu) na swoim (czyli i-tym) semaforze metodę V(). Następnie jedzie w pętli do wszystkich semaforach i dla każdego z nich (poza swoim, czyli i-tym) woła metodę P().

Tak wynika z przykładu, który podałeś.

0

Zrobiłem, dzięki. Teraz czas pomyśleć nad jakimś prostym przykładem, który z tej implementacji skorzysta...

0

Taki przykład, dajmy na to:

process Worker3{
        V(arrive3)        //sygnalizuj przybycie partneroem
        V(arrive3)//sygnalizuj przybycie partneroem
        P(arrive1) //czekaj na pierwszy watek
        P(arrive2)//czekaj na drugi watek
        ...//przejscie bariery przez W3
/************ i tutaj jakies operacje na zmiennej dzielonej*************/

}

jest do przejścia?? :)

0

Nie wiem, co chciałeś przekazać przez ten przykład. Zrób taki test, jak Ci pokazywałem z sekcją krytyczną. Dwie zmienne i do jednej dostęp jest niesynchronizowany a do drugiej synchronizowany. I wypisz wyniki. Ale zrób to dla 100 workerów np.

0

To nie ja chcialem, w ogóle przykład ten mi się nie podoba - chciał prowadzący ;). Mówiąc to co mi pokazywałeś, masz na myśli link do CountDownLatch?

0

Witaj, tak - kod, który podesłałeś to ten, o ktory mi chodzilo:
http://wklej.to/tJ2l

A co do tego "co juz pokazywalem", to nie pamietam, o co chodzilo ;) Niewazne ;) W kazdym razie rozumiesz juz, o co mi chodzilo - tak wynika z kodu, ktory zamiesciles.

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