Di nuovo sui Thread

di il
16 risposte

16 Risposte - Pagina 2

  • Re: Di nuovo sui Thread

    tagan ha scritto:


    ho visto altri esempi in cui si trova in un ciclo while e usano una variabile booleana che viene settata al termine di una certa operazione. una cosa del genere:
    Sì ma è solo un caso d'esempio. Quello che conta è la condizione in generale. Potrebbe essere appunto una variabile booleana a true (o false), un contatore uguale 0, oppure una lista "vuota", ecc...
    Finché "regge" questa condizione, il thread corrente deve stare/restare in wait.

    tagan ha scritto:


    e quello più strano join...!
    A dire il vero, join() è uno dei più semplici da capire. E tra l'altro non c'entra nulla con il lock intrinseco degli oggetti (né con i wait/notify).
    Il join serve banalmente per attendere la terminazione di un altro thread.
    // Sono nel thread A
    //...
    threadB.join();    // attende la fine del thread B
    // qui sono certo che thread B è terminato
    È anche questo un meccanismo di sincronizzazione ma non c'entra appunto con i lock.
  • Re: Di nuovo sui Thread

    andbin ha scritto:


    Sì ma è solo un caso d'esempio. Quello che conta è la condizione in generale. Potrebbe essere appunto una variabile booleana a true (o false), un contatore uguale 0, oppure una lista "vuota", ecc...
    Finché "regge" questa condizione, il thread corrente deve stare/restare in wait.
    Ciao.
    Pare che finalmente ho trovato la soluzione. mi sembra tutto corretto. testato molte volte e non ho mai avuto una Exception, tutti i thread terminano correttamente, le 3 Piste/risorse funzionano contemporaneamente da un solo thread per volta.
    Se ti va, puoi darci un'occhiata e dirmi se può andar bene e/o può essere migliorato?

    A parte le variabili di classe che le ho usate male, ma per questo esempio va bene.....
    
    import java.util.ArrayList;
    
    public class Tester {
    
    	static Aereo[] aerei = new Aereo[10];
    	static ArrayList<Pista> piste = new ArrayList<>();
    
    	public static void main(String[] args) {
    		/*
    		 * Questo programma mette a disposizione 3 Piste (Risorse)
    		 * per 10 Aerei (Thread) che devono decollare
    		 * tutti posso contemporaneamente fare i controlli PreVolo e attendere Random(1-10) secondi 
    		 * dopo possono usare le 3 piste e decollare in Random(1-10) secondi. Le tre piste devono essere usate ognuna da 1 thread e eseguite contemporaneamente
    		 * gli altri Aerei devono aspettare che gli aerei che hanno terminato la prima fase (i controlli prevolo) abbiano decollato e almeno una pista sia tornata libera
    		 */
    		crea10Aerei();
    		crea3Piste();
    		for (int i=0;i<aerei.length;i++) {
    			aerei[i].start();
    		}
    	}
    	static void crea10Aerei() {
    		for (int i=0;i<aerei.length; i++) {
    			aerei[i] = new Aereo("Aereo " + i);
    		}
    	}
    	
    	static void crea3Piste() {
    		for (int i=0;i<3; i++) {
    			piste.add(new Pista("Pista " + i));
    		}
    	}
    }
    
    public class Aereo extends Thread{
    	private String nome;
    	private Pista pista;
    	
    	public Aereo (String nome) {
    		this.nome=nome;
    	}
    
    	@Override
    	public void run() {
    		TorreDiControllo.getInstance().controlliPreVolo(this);
    		pista = TorreDiControllo.getInstance().assegnaPista(this);
    		pista.decolla(nome);
    		TorreDiControllo.getInstance().rilasciaPista(pista);
    	}
    
    	@Override
    	public String toString() {
    		return nome;
    	}
    }
    
    public class Pista {
    	private String nome;
    	
    	public Pista(String nome) {
    		this.nome=nome;
    	}
    	
    	public String getNome() {
    		return nome;
    	}
    
    	public synchronized void decolla(String aereo) {
    		int secondi = (int)(Math.random()*10) + 1;
    		System.out.println(aereo + " sta decollando da " + this.getNome() + " in " + secondi + " secondi!");
    		try { wait(secondi * 1000); } catch (InterruptedException e) { e.printStackTrace(); }
    		System.out.println(aereo + " è decollato e la pista " + this.getNome() + " è libera!");
    	}
    
    	@Override
    	public String toString() {
    		return nome;
    	}
    }
    
    public class TorreDiControllo {
    	private static TorreDiControllo instance; 
    
    	public synchronized static TorreDiControllo getInstance() {
    		if (instance == null) {
    			instance = new TorreDiControllo();
    		}
    		return instance;
    	}
    	
    	public synchronized void controlliPreVolo(Aereo aereo) {
    		int secondi = (int)(Math.random()*10) + 1;
    		System.out.println(aereo + " ha INIZIATO I CONTROLLI prevolo. termina in " + secondi + " secondi!");
    		try { wait(secondi * 1000); } catch (InterruptedException e) { e.printStackTrace(); }
    		System.out.println(aereo + " ha TERMINATO i controlli prevolo!");
    	}
    	
    	public synchronized Pista assegnaPista(Aereo aereo) {
    		while(Tester.piste.size()==0) {
    			try { wait(); } catch (InterruptedException e) { e.printStackTrace(); }
    		}
    		Pista pista = Tester.piste.remove(Tester.piste.size() -1);
    		return pista;
    	}
    	
    	public synchronized void rilasciaPista(Pista pista) {
    		Tester.piste.add(pista);
    		notifyAll();
    	}
    }
    
    Grazie, ciao
    Tagan
Devi accedere o registrarti per scrivere nel forum
16 risposte