[java] Thread

di il
5 risposte

[java] Thread

Ciao a tutti.
Ho il seguente esercizio: Ho una squadra di operai che devono costruire le pareti di una casa a base quadrata.
Gli operai sono divisi in due categorie: quelli che mettono il cemento e quelli che mettono i mattoni
Ogni parete viene costruita alternando uno strato di cemento e uno di mattone, fino ad un numero N.
All'interno della classe mi viene chiesto di implementare due metodi:
-boolean inizia(int i) che sospende l'operaio fino a quando non è disponibile il lavoro di tipo T, restituisce false se non ci sono più lavori da effettuare, true altrimenti
-void termina(): permette all'operaio di comunicare che ha terminato il proprio lavoro.
Io ho implementato la classe Operaio nel seguente modo:

import java.util.concurrent.TimeUnit;

public class Muratore extends Thread {
	private Casa casa;
	private static int id;
	private static int[] materiale = { 5, 7 };
	private static final int TEMPO_LAVORO = 1;
	private static final int TEMPO_RIPOSO = 5;

	public Muratore(Casa casa, int id) {
		this.casa = casa;
		this.id = id;
	}// costruttore

	public void run() {
		try {


				preparaMateriale(materiale[id]);
				while(casa.inizia(id)) {
					// System.out.println("Il muratore di tipo "+id+" inizia il
					// lavoro");
					lavora(TEMPO_LAVORO);
					// System.out.println("Il muratore di tipo "+id+" termina il
					// lavoro");
					casa.termina();
					riposa(TEMPO_RIPOSO);
			}
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
	}// run

	

	private void preparaMateriale(int m) throws InterruptedException {
		TimeUnit.SECONDS.sleep(m);
	}// preparaMateriale

	private void lavora(int t) throws InterruptedException {
		TimeUnit.SECONDS.sleep(t);
	}// lavora

	private void riposa(int t) throws InterruptedException {
		TimeUnit.SECONDS.sleep(t);
	}// riposa

}// Muratore
E la classe principale cosi:
public class CasaSem extends Casa {
	private Semaphore mutex = new Semaphore(1);
	private Semaphore[] muratori = new Semaphore[2];
	private boolean termine = false;
	private int indice = 0;
	private int turno = -1;

	public CasaSem(int fileMattoni) {
		super(fileMattoni);
		muratori[0]=new Semaphore(1);
		muratori[1]=new Semaphore(0);
	}// costruttore

	@Override
	public boolean inizia(int t) throws InterruptedException {
		// sospende il muratore fin quando non è diponibile il lavoro t
		// return false se non ci sono più lavori, true altrimenti
		muratori[t].acquire();
	
		if (numLavoriDaFare == 0) {
			// muratori[t].release();
			// muratori[1 - t].release();
		
			return false;

		} else {
			System.out.println("Il muratore di tipo " + t + " inizia il lavoro");
			
			return true;
		}

	}// inizia

	@Override
	public void termina() throws InterruptedException {
		// permette al muratore di comunicare che ha terminato il proprio lavoro
		mutex.release();
		System.out.println("Il muratore di tipo " + turno+ " ha terminato il lavoro");
		pareti[indice]++;
		numLavoriDaFare--;
		if (pareti[indice] == fileMattoni) {
			indice++;
			System.out.println("nuova parete");
			muratori[turno].release();
		} else {
			System.out.println("Il muratore ha terminato il lavoro");
			turno = (turno + 1) % 2;
			muratori[turno].release();
		}
		mutex.release();
	}// termina

	public static void main(String[] args) {
		int N = 6;
		Casa casa = new CasaSem(N);
		casa.test(5,7);
	}// main

}// CasaSem
Ma il codice non va come dovrebbe andare. Qualcuno sa darmi qualche consiglio??
Grazie

5 Risposte

  • Re: [java] Thread

    Rossella92 ha scritto:


    Ho il seguente esercizio: Ho una squadra di operai che devono costruire le pareti di una casa a base quadrata.
    Gli operai sono divisi in due categorie: quelli che mettono il cemento e quelli che mettono i mattoni
    Ogni parete viene costruita alternando uno strato di cemento e uno di mattone, fino ad un numero N.
    All'interno della classe mi viene chiesto di implementare due metodi:
    -boolean inizia(int i) che sospende l'operaio fino a quando non è disponibile il lavoro di tipo T, restituisce false se non ci sono più lavori da effettuare, true altrimenti
    -void termina(): permette all'operaio di comunicare che ha terminato il proprio lavoro.
    A parte il tuo codice (che potrebbe essere più o meno giusto .. non ho molto tempo stasera di leggerlo in dettaglio), quando fai esercizi di questo tipo (te lo dico in generale) dovresti sempre precisare bene che cosa deve essere "garantito" (per requisito) e cosa invece può essere lasciato "arbitrario". Perché con il multi-threading ... è così ...

    Allora: da quanto deduco, tu passi id=0 a tutti i muratori di un certo tipo (es. per "cemento") e id=1 a tutti i muratori dell'altro tipo (es. per "mattoni"), giusto? E ci deve essere "alternanza", 0 1 0 1 0 1 0 1 ecc.... giusto? Cioè due muratori dello STESSO tipo NON devono poter operare consecutivamente, giusto? (questo sarebbe il requisito da "garantire")

    Bene, allora innanzitutto hai bisogno solo di 2 oggetti Semaphore. Ma li devi gestire oculatamente. Supponiamo che il primo a poter avere il permesso è id=0. Un solo muratore 0 quindi acquisisce il permesso al semaforo [0].
    Quando questo muratore invoca termina(), attenzione, NON devi rilasciare questo permesso al semaforo [0] (altrimenti un altro muratore dello stesso tipo potrebbe ripartire!). Devi dare 1 permesso all'altro tipo. Quando un altro muratore id=1 riesce a prendere il permesso al semaforo [1] poi, quando termina, deve rilasciare il permesso [0], NON il suo.

    Solo così puoi garantire l'alternanza. Ti è più chiaro? Ti assicuro che è più semplice di quanto credi o hai già fatto ...
  • Re: [java] Thread

    Allora: da quanto deduco, tu passi id=0 a tutti i muratori di un certo tipo (es. per "cemento") e id=1 a tutti i muratori dell'altro tipo (es. per "mattoni"), giusto? E ci deve essere "alternanza", 0 1 0 1 0 1 0 1 ecc.... giusto? Cioè due muratori dello STESSO tipo NON devono poter operare consecutivamente, giusto? (questo sarebbe il requisito da "garantire")
    Si questo è quello che devo garantire.
    Il ragionamento l’ho capito, però quando nel metodo termina(int t) vado a fare:
    t=(t+1)%2
    muratori[t].release()
    Non va ugualmente!

    Poi nel costruttore posso scrivere:
    for(int i=0;i<muratori.length;i++){
    muratori= new Semaphore(0);
    }
    muratori[0]=new Semaphore(1);
  • Re: [java] Thread

    Rossella92 ha scritto:


    Il ragionamento l’ho capito, però quando nel metodo termina(int t) vado a fare:
    t=(t+1)%2
    muratori[t].release()
    Non va ugualmente!
    Prima l'ho spiegato concettualmente. Ma siccome nel termina() NON passi alcun id, è abbastanza chiaro che devi tenerti da parte quale è il id "corrente", in modo da determinare quale è l'altro.
    Però vedo che turno lo fai partire a -1, non lo tocchi al inizia() e quindi al primissimo termina() fai muratori[-1].release();
    Quindi ti lascio immaginare cosa succede con quel -1 ...

    Poi hai messo quel Semaphore mutex che direi non ti serve proprio.

    Rossella92 ha scritto:


    Poi nel costruttore posso scrivere:
    for(int i=0;i<muratori.length;i++){
    muratori[i]= new Semaphore(0);
    }
    muratori[0]=new Semaphore(1);
    No, alt, perché?? Se hai N muratori, non devi fare N semafori ... solo 2 (per i due tipi).
  • Re: [java] Thread

    No, alt, perché?? Se hai N muratori, non devi fare N semafori ... solo 2 (per i due tipi).
    muratori.length è uguale a 2.
    Ho riscritto così:
    public boolean inizia(int t) throws InterruptedException{
    muratori[t].acquire();
    if(numLavoriDaFare==0){
    muratori[t].release();
    muratori[1-t].release();
    termine=false;
    else{
    System.out.println(“Il muratore di tipo”+t+ “inizia a lavorare”);
    termine=true;
    }
    return termine;
    }
    public void termina(int t) throws InterruptedException{
    mutex.acquire();
    fileRimaste—;
    numLavoriDaFare—;
    if(fileRimaste==0){
    pareti—;
    fileRimaste+=fileMattoni;
    muratori[0].release();
    }else{
    t=(t+1)%2;
    muratori[t].release();
    }
    mutex.release();
    }
    mutex.release();
    }
  • Re: [java] Thread

    Esercizio risolto.
    Grazie sempre per l’aiuto
Devi accedere o registrarti per scrivere nel forum
5 risposte