PDA

View Full Version : [Java] Threads e wait()


SteR9
28-04-2006, 23:05
Ragazzi sto studiando un pò i thread in java, in particolare la loro sincronizzazione. Quello che voglio è creare 2 threads che eseguono una operazione per uno, una dietro l'altra.
Io pensavo di eseguire un thread metterlo in wait e svegliare l'altro.
Ho creato queste 3 classi:


public class oggetti {
boolean read_state = false;
boolean write_state = false;

public synchronized void read() throws InterruptedException {
System.out.println("Lettore:");
notifyAll();
while(read_state != true)
wait();
}

public synchronized void write() throws InterruptedException {
System.out.println("invio:");
notifyAll();
while(write_state != true)
wait();
}

public void setReadState(boolean s){
read_state = s;
}

public void setWriteState(boolean s){
write_state = s;
}
}


public class thread_reader implements Runnable {

public void run() {
oggetti o = new oggetti();
try {
while (true) {
o.read();
o.setWriteState(true);
o.setReadState(false);
}
} catch (InterruptedException e) {
}
}
}


public class thread_writer implements Runnable {
public void run() {
oggetti o = new oggetti();
try {
while (true) {
o.write();
o.setWriteState(false);
o.setReadState(true);
}
} catch (InterruptedException e) {
}
}
}


il programma parte e i thread stampano una volta soltanto il messaggio, dopo è come se rimanessero sempre in wait. E' sbagliato il metodo che ho usato?

SteR9
29-04-2006, 20:45
UP :cry:

franksisca
29-04-2006, 21:24
il notify fallo dopo.....

SteR9
30-04-2006, 04:05
avevo già provato ma non cambia niente, non va lo stesso :cry:

franksisca
30-04-2006, 12:06
aspetta che adesso vedo megklio;)

theClimber
30-04-2006, 12:07
Ma come lanci il programma? riesci a postare il codice che avvia i thread?

Non mi torna il fatto che di istanze di oggetti ne hai 2, una per thread. Mi sembra normale che non succeda niente ed i due thread non comunichino dato che usano due lock diversi.

SteR9
30-04-2006, 13:15
si hai ragione, infatti poi ho corretto, ma non funziona lo stesso :fagiano:. Posto il codice corretto e anche il main..

public class oggetti {
boolean read_state = false;
boolean write_state = false;

public synchronized void read() throws InterruptedException {
System.out.println("Lettore:");
while(read_state != true)
wait();

notifyAll();
}

public synchronized void write() throws InterruptedException {
System.out.println("invio:");
while(write_state != true)
wait();

notifyAll();
}

public void setReadState(boolean s){
read_state = s;
}

public void setWriteState(boolean s){
write_state = s;
}

public synchronized void wwait() throws InterruptedException {
wait();
}
}

public class thread_reader implements Runnable {

oggetti o;

public void run() {
try {
while (true) {
o.read();
o.setWriteState(true);
o.setReadState(false);
}
} catch (InterruptedException e) {
}
}

public void setO(oggetti o){
this.o = o;
}
}
public class thread_writer implements Runnable {
oggetti o;

public void run() {

try {
while (true) {
o.write();
o.setWriteState(false);
o.setReadState(true);
}
} catch (InterruptedException e) {
}
}

public void setO(oggetti o) {
this.o = o;
}
}
public class ProvaThread {
public static void main(String[] argv) {
thread_reader r = new thread_reader();
thread_writer w = new thread_writer();
oggetti o = new oggetti();

r.setO(o);
w.setO(o);

Thread re = new Thread(r);
Thread wr = new Thread(w);

re.start();
wr.start();
}
}

ho provato anche a mettere una sleep sul secondo thread per farlo partire ritardato perchè avevo paura che i thread venissero eseguiti in parallelo e quindi si mettevano in wait nello stesso istante e quindi rimanevano sempre in wait, ma non funziona lo stesso. :cry:

theClimber
30-04-2006, 13:38
Visto il codice mi smebra giusto che non succeda niente:

Quando lanci i thread, entrambi vanno in wait, sullo stesso lock. Non ci sarà mai alcun notify in queste condizioni.

Come mai devi metterti in wait anche sul write? fai una prova di questo tipo:
- Mantieni il wait sul read, e quando si riattiva satmpi il valore scritto
- Il write non fa alcuna wait, ma dopo aver scritto fa notify per risvegliare chi legge

Ciao

SteR9
30-04-2006, 15:05
il write fa una wait perchè deve aspettare che read venga eseguito e a sua volta read fa una wait perchè deve aspettare che write venga eseguito.
Se io tolgo la wait sul write il write viene eseguito molte più volte di quante viene eseguito read.

Elyon
30-04-2006, 21:10
Se le due variabili sono a false e nessuno le setta a true, come fanno i 2 thread ad uscire dal while (dato che entrambi settano a true le rispettive variabili solo dopo aver letto o scritto)? Credo che sia questo il problema...

SteR9
30-04-2006, 22:18
Infatti me ne ero accorto e ho messo read a true visto che è il primo che deve partire.. ma non va lo stesso! :muro:

FedeX_65246X
05-05-2006, 00:52
Utilizzerei una sola variabile di stato

boolean isReading

e mi assicurerei di leggerla e modificarla solo in un contesto di accesso esclusivo.