Linguaggi di programmazione: php, perl, python, C, bash e tutti gli altri.
TommyB1992
Scoppiettante Seguace
Messaggi: 862 Iscrizione: domenica 7 luglio 2013, 15:55
Desktop: GNU/Linux
Distribuzione: Ubuntu 22.04.2 LTS
Sesso: Maschile
Messaggio
da TommyB1992 » martedì 16 aprile 2024, 14:51
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?
DoctorStrange
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
Messaggio
da DoctorStrange » martedì 16 aprile 2024, 15:02
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
Messaggi: 862 Iscrizione: domenica 7 luglio 2013, 15:55
Desktop: GNU/Linux
Distribuzione: Ubuntu 22.04.2 LTS
Sesso: Maschile
Messaggio
da TommyB1992 » martedì 16 aprile 2024, 15:43
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
DoctorStrange
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
Messaggio
da DoctorStrange » martedì 16 aprile 2024, 15:56
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
Messaggi: 862 Iscrizione: domenica 7 luglio 2013, 15:55
Desktop: GNU/Linux
Distribuzione: Ubuntu 22.04.2 LTS
Sesso: Maschile
Messaggio
da TommyB1992 » martedì 16 aprile 2024, 16:35
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
DoctorStrange
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
Messaggio
da DoctorStrange » martedì 16 aprile 2024, 16:44
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
Messaggi: 862 Iscrizione: domenica 7 luglio 2013, 15:55
Desktop: GNU/Linux
Distribuzione: Ubuntu 22.04.2 LTS
Sesso: Maschile
Messaggio
da TommyB1992 » martedì 16 aprile 2024, 16:50
Ho capito dove sbaglio, sto sincronizzando l'istanza dell'oggetto stesso.
E comunque, in java, i mutex non esistono.
DoctorStrange
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
Messaggio
da DoctorStrange » 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.
TommyB1992
Scoppiettante Seguace
Messaggi: 862 Iscrizione: domenica 7 luglio 2013, 15:55
Desktop: GNU/Linux
Distribuzione: Ubuntu 22.04.2 LTS
Sesso: Maschile
Messaggio
da TommyB1992 » martedì 16 aprile 2024, 18:54
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...
Visualizzano questa sezione: 0 utenti iscritti e 3 ospiti