[java] semafori e thread

di il
9 risposte

[java] semafori e thread

Ciao a tutti, ho iniziato da poco a studiare la programmazione concorrente.
Ho svolto un primo esercizio dove mi chiedeva di realizzare un'applicazione multithreaded composta da due tipologie di thread: A e B.
Ogni thred della classe A stampa a video,una sola volta,la stringa <<A>> e poi termina la sua esecuzione.
Lo stesso fa un Thread della classe B stampando la stringa <<B>>. Il main deve inzializzare ogni secondo un thread di tipo A e un thread di tipo B. L'output che si genera è:
AAB AAB AAB AAB
Allego il codice

public class AAB1 {
private static Semaphore semA = new Semaphore(2);
private static Semaphore semB = new Semaphore(0);

static class A extends Thread {
public void run() {
try {
semA.acquire();
System.out.print("A");
semB.release();
} catch (InterruptedException e) {
e.printStackTrace();
}
}// run
}// A

static class B extends Thread {
public void run() {
try {
semB.acquire(2);
System.out.print("B" + " ");
semA.release(2);
} catch (InterruptedException e) {
e.printStackTrace();
}
}// run
}// B

public static void main(String[] args) {
while (true) {
new A().start();
new B().start();
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}

}

Se volessi generare,invece,l'output AA BB AA BB ... come dovrei gestire i semafori?
Qualcuno sa darmi qualche consiglio?
Grazie

9 Risposte

  • Re: [java] semafori e thread

    Rossella92 ha scritto:


    Se volessi generare,invece,l'output AA BB AA BB ... come dovrei gestire i semafori?
    Beh, inizia innanzitutto a ragionare su questo. Per avere le prime due "A", devono essere creati 2 thread A, fin qui ovvio. Se il semA ha inizialmente 2 permit, il primo A ne prende uno, poi il secondo A ne prende un'altro. Ma il punto è che ciascuno dopo aver stampato "A" al momento attuale (per come l'hai scritto) fa un release su semB. Mentre in teoria solo il secondo A dovrebbe dare 2 permit a B.
  • Re: [java] semafori e thread

    Il codice che ho scritto è relativo all'output AAB AAB AAB...
    Il problema è che non riesco a capire bene il ragionamento che sta dietro ai metodi dei semafori.
    Cioè se dichiaro un semaforo "Semaphore semA=new Semaphore(2)" vuol dire che 2 thread possono accedere ad esso.
    [Mentre in teoria solo il secondo A dovrebbe dare 2 permit a B] e come dovrei farlo?
  • Re: [java] semafori e thread

    Rossella92 ha scritto:


    Il problema è che non riesco a capire bene il ragionamento che sta dietro ai metodi dei semafori.
    Cioè se dichiaro un semaforo "Semaphore semA=new Semaphore(2)" vuol dire che 2 thread possono accedere ad esso.
    Un semaforo ha un numero N di "permessi" (permit in inglese). Quando fai un acquire() ne prendi uno. Quando fai un release() lo rilasci (per renderlo disponibile ad altri). Quando il numero di permessi in un certo istante è 0 e un thread fa un acquire(), si blocca e resta lì in attesa di poterne prendere uno.

    Rossella92 ha scritto:


    come dovrei farlo?
    O con un tuo contatore o magari guardando quanti permit ci sono. Se partendo con semA con 2 permessi ad un certo punto ce ne sono 0, vuol dire che 2 A sono passati. A quel punto dai 2 permessi per B. E così al contrario da B ad A.
  • Re: [java] semafori e thread

    Ho provato a scrivere questo codice ma mi stampa ABABABAB...
    public class AABB {
    private static Semaphore semA = new Semaphore(2);
    private static Semaphore semB = new Semaphore(2);

    static class A extends Thread {
    public void run() {
    try {
    semA.acquire();
    System.out.print("A");
    semB.release(2);
    } catch (InterruptedException e) {
    e.printStackTrace();
    }
    }// run
    }// A

    static class B extends Thread {
    public void run() {
    try {
    semB.acquire();
    System.out.print("B");
    semA.release(2);

    } catch (InterruptedException e) {
    e.printStackTrace();
    }
    }// run
    }// B

    public static void main(String[] args) {
    while (true) {
    new A().start();
    new B().start();
    try {
    TimeUnit.SECONDS.sleep(1);
    } catch (InterruptedException e) {
    e.printStackTrace();
    }
    } // while
    }// main
    }// AABB
  • Re: [java] semafori e thread

    Rossella92 ha scritto:


    Ho provato a scrivere questo codice ma mi stampa ABABABAB...
    Innanzitutto, all'inizio semB deve avere 0 permit ... altrimenti B ci passa subito!

    Poi comunque l'ho detto prima e lo ripeto: non puoi fare un release "indiscriminato" di 2 permit. Devi testare se sono "passati" 2 thread nel acquire e nel print. E questo lo fai o con un tuo contatore che ti tieni da parte, oppure andando a vedere quanti permit sono rimasti nel semaforo.
  • Re: [java] semafori e thread

    Scrivendo cosi mi da come output AABB però solo una volta
    public class AABB {
    private static Semaphore semA = new Semaphore(2);
    private static Semaphore semB = new Semaphore(0);
    private static int count = 0;


    static class A extends Thread {
    public void run() {
    try {
    semA.acquire();
    System.out.print("A");
    count++;
    if (count == 2)
    semB.release(2);
    } catch (InterruptedException e) {
    e.printStackTrace();
    }
    }// run
    }// A

    static class B extends Thread {
    public void run() {
    try {
    semB.acquire();
    System.out.print("B");
    count++;
    if (count == 2)
    semA.release(2);

    } catch (InterruptedException e) {
    e.printStackTrace();
    }
    }// run
    }// B

    public static void main(String[] args) {
    while (true) {
    new A().start();
    new B().start();
    try {
    TimeUnit.SECONDS.sleep(1);
    } catch (InterruptedException e) {
    e.printStackTrace();
    }
    } // while
    }// main
    }// AABB
  • Re: [java] semafori e thread

    Ho risolto cosi:
    public class AABB {
    private static Semaphore semA = new Semaphore(2);
    private static Semaphore semB = new Semaphore(0);


    static class A extends Thread {
    public void run() {
    try {
    semA.acquire();
    System.out.print("A");
    if (semA.availablePermits() == 0)
    semB.release(2);
    } catch (InterruptedException e) {
    e.printStackTrace();
    }
    }// run
    }// A

    static class B extends Thread {
    public void run() {
    try {
    semB.acquire();
    System.out.print("B");
    if (semB.availablePermits() == 0)
    semA.release(2);

    } catch (InterruptedException e) {
    e.printStackTrace();
    }
    }// run
    }// B

    public static void main(String[] args) {
    while (true) {
    new A().start();
    new B().start();
    try {
    TimeUnit.SECONDS.sleep(1);
    } catch (InterruptedException e) {
    e.printStackTrace();
    }
    } // while
    }// main
    }// AABB
    Grazie
  • Re: [java] semafori e thread

    Rossella92 ha scritto:


    Ho risolto cosi:
    Corretto! I due test con availablePermits() == 0 sono esattamente ciò che serve.

    Anche con il contatore poteva funzionare ... solo che non hai ragionato su una cosa: il contatore va resettato, cioè da 2 deve tornare a 0.
  • Re: [java] semafori e thread

    E' vero, c'ho pensato dopo in effetti.
    Grazie per l'aiuto.
Devi accedere o registrarti per scrivere nel forum
9 risposte