View Full Version : [Java - Java Thread] help attendere gli utenti
ciao ragazzi...
vi spiego la situazione:
nel mio main vengono creati 5 giocatori (tramite un for che rifà a Giocatori.java).... e vengono creati giusti e tutto ok.
dopo ogni start(), c'è anche un metodo chiamato giocatoriPronti, che si incrementa. Quindi 5 giocatori, giocatoriPronti=5.
Giocatore[] giocatore = new Giocatore[5];
for (int i=0; i<5; i++){
giocatore[i]=new Giocatore(i,tavolo);
System.out.println("Giocatore "+i+" creato");
giocatore[i].start();
tavolo.giocatoriPronti();
System.out.println("Giocatore "+i+" lanciato");
tavolo è un .java pieno di metodi.
Ora, ho un .java chiamato Arbitro, che prima di fare qualunque cosa, controlla che vi siano gli utenti...
public void attendiGiocatori(){
synchronized(syncGiocatoriPronti){
while(tavolo.getGiocatoriPronti()<5){
System.out.println("NO "+tavolo.giocatoriPronti);
try{
syncGiocatoriPronti.wait();
}
catch (InterruptedException e){
e.printStackTrace();
}
}
System.out.println("SI "+tavolo.giocatoriPronti);
}
}
getGiocatoriPronti è semplicemente un metodo che dà un return della variabile giocatoriPronti (che come spiegato prima diventa 5, incrementandosi).
ma.............. il tutto non funziona. quando lancio dal prompt, rimane tutto in attesa, come se Arbitro non rilevasse che ci sono 5 giocatori, e quindi rimane in wait..............
mi sapete aiutare???
Don[ITA]
11-01-2009, 16:26
Serve più codice per capire dove si incasinano i thread.
Chi chiama il metodo attendiGiocatori()?
Saluti
;25796706']Chi chiama il metodo attendiGiocatori()?
Saluti
lo chiama Arbitro.java
Don[ITA]
11-01-2009, 17:39
Lo chiama solo lui?
Se si non dovrebbe servire quel synchronized :eh:
Se puoi posta l'intero codice così riusciamo ad aiutarti :)
Saluti
io lo posto anche. è tanto, ma va beh eheheh
tolgo un pò di roba che non serve di sicuro.
Main
public class Main{
public static void main(String[] args){
Tavolo tavolo = new Tavolo();
Arbitro arbitro = new Arbitro(tavolo);
System.out.println("Arbitro creato");
arbitro.start();
System.out.println("Arbitro lanciato");
Giocatore[] giocatore = new Giocatore[5];
for (int i=0; i<5; i++){
giocatore[i]=new Giocatore(i,tavolo);
System.out.println("Giocatore "+i+" creato");
giocatore[i].start();
tavolo.giocatoriPronti();
System.out.println("Giocatore "+i+" lanciato");
}
try{
arbitro.join();
}
catch(Exception e){
System.out.println("ERRORE JOIN MAIN: "+e);
}
}
}
Arbitro
public class Arbitro extends Thread{
private Tavolo tavolo;
private Object syncGiocatoriPronti;
private long orologio=System.currentTimeMillis();
public Arbitro(Tavolo t) {
super("Arbitro");
tavolo = t;
syncGiocatoriPronti=new Object();
}
public void run(){
attendiGiocatori();
System.out.println("Benvenuti a tutti!!!");
-----------qua ho tolto codice che non centra-----------
}
public void attendiGiocatori(){
synchronized(syncGiocatoriPronti){
while(tavolo.getGiocatoriPronti()<5){
System.out.println("NO "+tavolo.giocatoriPronti);
try{
syncGiocatoriPronti.wait();
}
catch (InterruptedException e){
e.printStackTrace();
}
}
System.out.println("SI "+tavolo.giocatoriPronti);
}
}
}
questi sono i metodi chiamati
int giocatoriPronti=0;
-----------qua ho tolto codice che non centra-----------
synchronized public void giocatoriPronti(){
giocatoriPronti++;
}
synchronized public int getGiocatoriPronti(){
return giocatoriPronti;
}
grazie a tutti, siete gentilissimi!!!!
Non sono sicuro di quello che dico perchè non ho testato, ma nel metodo giocatoriPronti() ci vorrebbe una bel notifyAll() per risvegliare tutti i girocatori
Non sono sicuro di quello che dico perchè non ho testato, ma nel metodo giocatoriPronti() ci vorrebbe una bel notifyAll() per risvegliare tutti i girocatori
ma notifyAll li non serve. cioè quel metodo è solo un ++ per la variabile, che poi quando viene letta dall'arbitro (e se è 5), fà si che il programma prosegua.
se non trovo via di scampo da questo problema, mi conviene studiare un modo per far partire i giocatori (e va beh qua nel main c'è lo start()), addormentarli, e farli svegliare dall'Arbitro quando mi serve. Anzi se qualcuno ha un idea...
Don[ITA]
11-01-2009, 22:54
Da quel che vedo, ti suggerirei caldamente di studiarti molto meglio la parte sui thread, sul loro utilizzo e sul loro controllo. In quel codice ci sono un sacco di errori che non stò nemmeno ad elencare :)
Cmq per darti un idea di sincronizzazione di thread simile a quella che vorresti ottenere tu, guardati questo codice:
public class ThreadSyncDemo {
public static void main(String[] args) {
new ThreadSyncDemo();
}
public ThreadSyncDemo() {
Tavolo tavolo = new Tavolo();
new Arbitro(tavolo).start();
new Giocatore(0, tavolo).start();
new Giocatore(1, tavolo).start();
new Giocatore(2, tavolo).start();
new Giocatore(3, tavolo).start();
new Giocatore(4, tavolo).start();
}
private class Giocatore extends Thread {
private Tavolo tavolo;
private int i;
public Giocatore(int i, Tavolo tavolo) {
this.i = i;
this.tavolo = tavolo;
}
@Override
public void run() {
System.out.println("Giocatore " + i + " inizia.");
tavolo.aggiungiGiocatore();
System.out.println("Giocatore " + i + " termina.");
}
}
private class Arbitro extends Thread {
private Tavolo tavolo;
public Arbitro(Tavolo tavolo) {
this.tavolo = tavolo;
}
@Override
public void run() {
System.out.println("Arbitro inizia.");
while(tavolo.getGiocatoriCollegati() < 5) {
System.out.println("Limite giocatori non ancora raggiunto.");
}
System.out.println("Arbitro termina.");
}
}
private class Tavolo {
private int giocatoriCollegati;
private final Object inUse;
public Tavolo() {
giocatoriCollegati = 0;
inUse = new Object();
}
public void aggiungiGiocatore() {
synchronized(inUse){
giocatoriCollegati++;
}
}
public int getGiocatoriCollegati() {
synchronized(inUse){
return giocatoriCollegati;
}
}
}
}
Se non ti è chiaro chiedi pure :D
:eek:
grazie mille!
quindi così posso gestire il problema da dio!
e ho anche capito il codice! il mio problema è che leggere codice riesco, ma poi partire da 0 per fare cose diverse, mi incasino.
grazie di cuore, nel caso posterò ancora :D
visto che sei disponibile ti chiedo una cosa.
se io voglio che arbitro fermi i giocatori, stampi a schermo 2 robe, faccia ripartire i giocatori (e qua intendo che il giocatore rifà il run()), dopo che fanno il run li riferma, e così via..... come faccio a farlo? (seguendo il filone delle cose che mi hai appena scritto)
sempre grazie e se puoi/vuoi;)
ehm.... il tuo codice di prima non va.
mi esce giocatori creati e ok ma poi esce una valanga di volte limite non raggiunto, poi ancora giocatori collegati, poi ancora limite, e poi arbitro termina.
parlo del tuo codice, il mio è commentato
ah ecco perchè non mi và. tu hai fatto tutto in un unico file .java (almeno che non hai scritto sbagliato il codice prima)
io invece o un file per ogni cosa....
giocatore.java
arbitro.java
tavolo.java
main.java
Don[ITA]
11-01-2009, 23:42
Si si era tutto in un unico file :D
Per quanto riguarda il fermare tutto e poi far ripartire dovresti usare wait() e notify() o notifyAll(). Ora vado a nanna che domani ho la leva alle 6 cmq domani appena torno ti posto dell'altro codice ;)
Notte a tutti :D
ok thanks!
cmq il tuo codice (proprio solo il tuo in un unico file) funziona, ma come mai prima dice 7 volte limite non raggionto, poi appaiono i giocatori, e poi dice ok.... non si può "reincastrare" le frasi per renderlo più ordinato?
ok ho messo anche io tutto in un unico file. e ho corretto usando il tuo codice, e funziona tutto :D ;)
Ora mi serve solo sapere queste 2 cose, e dopo posso dire grazie di cuore e non romperò più le balle, promesso :p
1)
se io voglio che arbitro fermi i giocatori, stampi a schermo 2 robe, faccia ripartire i giocatori (e qua intendo che il giocatore rifà il run()), dopo che fanno il run li riferma, e così via..... come faccio a farlo?
2)
se ho nel run di giocatore, un while{Arbitro.a==7){...}, e a lo modifica Arbitro (durante il suo run)........... come faccio a far capire al giocatore che questa a è 7 (e quindi lui esce dal while e prosegue le sue storie)
fine, giuro poi non sasso più :-)
siete un forum magnifico :-)
vBulletin® v3.6.4, Copyright ©2000-2025, Jelsoft Enterprises Ltd.