[Java] Thread con notify/wait

Linguaggi di programmazione: php, perl, python, C, bash e tutti gli altri.
TommyB1992
Scoppiettante Seguace
Scoppiettante Seguace
Messaggi: 862
Iscrizione: domenica 7 luglio 2013, 15:55
Desktop: GNU/Linux
Distribuzione: Ubuntu 22.04.2 LTS
Sesso: Maschile

[Java] Thread con notify/wait

Messaggio da TommyB1992 »

Sto cercando di studiare un pò di JAVA facendo una semplice simulazione di "PingPong" (dove un thread dice Ping e l'altro pong) con l'utilizzo di wait e notify

Codice: Seleziona tutto

/* Main.java */
package global;

public class Main {
	public static void main(String[] args) {
		Thread ping = new Thread(new PingPong(), "Ping");
		Thread pong = new Thread(new PingPong(), "Pong");
		
		ping.start();
		try {
			Thread.sleep(3000);
		}
		catch (InterruptedException e) {}
		pong.start();
		
		try {
			ping.join();
			pong.join();
		} catch (InterruptedException e) {}
	}

}

/* PingPong.java */
package global;

public class PingPong implements Runnable {
	@Override
	public void run() {
		while (true) {
			synchronized (this) {
				System.out.println(Thread.currentThread().getName());
	
				this.notify();
				try {
					this.wait();
				}
				catch (InterruptedException e) {
					e.printStackTrace();
				}
			}
		}
	}
}
Dove sbaglio?
Avatar utente
DoctorStrange
Imperturbabile Insigne
Imperturbabile Insigne
Messaggi: 2924
Iscrizione: mercoledì 14 ottobre 2015, 9:33
Desktop: Gnome3
Distribuzione: Ubuntu 22.04 LTS Jammy Jellyfish
Sesso: Maschile
Località: Roma, Italia

Re: [Java] Thread con notify/wait

Messaggio da DoctorStrange »

Sia ping che pong vengono avviati in parallelo perche la sleep non viene eseguita nel thread di ping. Questo vuol dire che pong non riceverà mai la notifica che ping ha completato la sua esecuzione. Per fare questo genere di cose si dovrebbero comunque usare librerie che prevengano proprio questo genere di deadlock e race conditions. Nel mio stack, io uso spesso "deferred" e "data monad". Non so di preciso in Java questo concetti da quale framework vengano implementati. comunque buona fortuna. La programmazione distribuita è molto divertente. Ti piacerà un sacco.
TommyB1992
Scoppiettante Seguace
Scoppiettante Seguace
Messaggi: 862
Iscrizione: domenica 7 luglio 2013, 15:55
Desktop: GNU/Linux
Distribuzione: Ubuntu 22.04.2 LTS
Sesso: Maschile

Re: [Java] Thread con notify/wait

Messaggio da TommyB1992 »

Ok, ma siccome non m'interessa adesso l'utilizzo di altre librerie, mi servirebbe una modifica alle 2 righe perché così io possa comprendere dove viene avviato cosa
Avatar utente
DoctorStrange
Imperturbabile Insigne
Imperturbabile Insigne
Messaggi: 2924
Iscrizione: mercoledì 14 ottobre 2015, 9:33
Desktop: Gnome3
Distribuzione: Ubuntu 22.04 LTS Jammy Jellyfish
Sesso: Maschile
Località: Roma, Italia

Re: [Java] Thread con notify/wait

Messaggio da DoctorStrange »

Tu vuoi avviare ping, lasciarlo in polling per tre secondi e, alla fine di questi, avviare il thread di pong?
Se è così, allora l'istruzione di sleep la devi mettere all'interno dello start di ping. Devi poi creare una struttura che faccia da mediatore. Un mutex. Pong andrà a leggere il mutex e, quando ping avrà notificato il completamento del suo processo al mutex, allora interverrà pong e farà il suo.
TommyB1992
Scoppiettante Seguace
Scoppiettante Seguace
Messaggi: 862
Iscrizione: domenica 7 luglio 2013, 15:55
Desktop: GNU/Linux
Distribuzione: Ubuntu 22.04.2 LTS
Sesso: Maschile

Re: [Java] Thread con notify/wait

Messaggio da TommyB1992 »

:sgrat:

Main.java

Codice: Seleziona tutto

package global;

public class Main {
	public static void main(String[] args) {
		PingPong ping = new PingPong();
		PingPong pong = new PingPong();
		
		System.out.println("--- Start ---");
		
		new Thread(ping, "Ping").start();
		new Thread(pong, "Pong").start();
	}
	
	public static void sleep(int secs) {
		try {
			Thread.sleep(secs * 1000);
		}
		catch (Exception e) {}
	}
}
PingPong.java

Codice: Seleziona tutto

public class PingPong implements Runnable {
	@Override
	public void run() {
		String name = Thread.currentThread().getName();
		System.out.println(name + " Inizializzato");
		
		for (int i = 0; ; i++) {
			synchronized (this) {
				if (i == 0) {
					if (name.equals("Ping")) {
						Main.sleep(3);
					}
					else {
						System.out.println(name + " si mette in wait");
						_wait();
					}
				}
				else {
					System.out.println(name);
		
					this.notify();
					System.out.println(name + " notifica e si mette in wait");
					_wait();
				}
			}
		}
	}
	
	private void _wait() {
		try {
			this.wait();
		}
		catch (InterruptedException e) {
			e.printStackTrace();
		}
	}
}
Output:

Codice: Seleziona tutto

--- Start ---
Ping Inizializzato
Pong Inizializzato
Pong si mette in wait
Ping si sveglia dallo sleep
Ping
Ping notifica e si mette in wait
Avatar utente
DoctorStrange
Imperturbabile Insigne
Imperturbabile Insigne
Messaggi: 2924
Iscrizione: mercoledì 14 ottobre 2015, 9:33
Desktop: Gnome3
Distribuzione: Ubuntu 22.04 LTS Jammy Jellyfish
Sesso: Maschile
Località: Roma, Italia

Re: [Java] Thread con notify/wait

Messaggio da DoctorStrange »

Se non usi il mutex, i due thread partono in parallelo. In funzione del congestionamento e della coda del tuo processore, tu non hai la garanzia che venga eseguito prima il ping e poi il pong.
TommyB1992
Scoppiettante Seguace
Scoppiettante Seguace
Messaggi: 862
Iscrizione: domenica 7 luglio 2013, 15:55
Desktop: GNU/Linux
Distribuzione: Ubuntu 22.04.2 LTS
Sesso: Maschile

Re: [Java] Thread con notify/wait

Messaggio da TommyB1992 »

Ho capito dove sbaglio, sto sincronizzando l'istanza dell'oggetto stesso.

E comunque, in java, i mutex non esistono.
Avatar utente
DoctorStrange
Imperturbabile Insigne
Imperturbabile Insigne
Messaggi: 2924
Iscrizione: mercoledì 14 ottobre 2015, 9:33
Desktop: Gnome3
Distribuzione: Ubuntu 22.04 LTS Jammy Jellyfish
Sesso: Maschile
Località: Roma, Italia

Re: [Java] Thread con notify/wait

Messaggio da DoctorStrange »

TommyB1992 ha scritto: E comunque, in java, i mutex non esistono.
Guarda, questo è il primo tra il milione di risultati trovati: https://www.baeldung.com/java-mutex

Comunque buona fortuna.
TommyB1992
Scoppiettante Seguace
Scoppiettante Seguace
Messaggi: 862
Iscrizione: domenica 7 luglio 2013, 15:55
Desktop: GNU/Linux
Distribuzione: Ubuntu 22.04.2 LTS
Sesso: Maschile

Re: [Java] Thread con notify/wait

Messaggio da TommyB1992 »

DoctorStrange ha scritto:
martedì 16 aprile 2024, 17:16
TommyB1992 ha scritto: E comunque, in java, i mutex non esistono.
Guarda, questo è il primo tra il milione di risultati trovati: https://www.baeldung.com/java-mutex

Comunque buona fortuna.
chiaro, se mi prendi una libreria terza trovi tutto, ma siccome sto imparando le basi e le funzioni native, come ho già scritto prima...
Scrivi risposta

Ritorna a “Programmazione”

Chi c’è in linea

Visualizzano questa sezione: 0 utenti iscritti e 3 ospiti