|
|
|
![]() |
|
Strumenti |
![]() |
#1 |
Senior Member
Iscritto dal: Mar 2004
Città: castel san giorgio(salerno)
Messaggi: 1218
|
Thread in Java
Ciao a tutti.
Sonno alle prese per la prima volta con i Thread in Java. Vi scrivo il mio problema: File OccupaSedia.java: import java.lang.InterruptedException; public class OccupaSedia extends Thread{ public int num_partecipanti; public int num_sedie; public int num_sessioni; public Sedia[] array_sedie; public String[] array_partecipanti; public Thread runner; Object obj="a"; int x = 0; public OccupaSedia(int a, int b, int c){ num_partecipanti = b; num_sedie = a; num_sessioni = c; //Creazione struttura per sedie e partecipanti array_sedie = new Sedia[num_sedie]; array_partecipanti = new String[num_partecipanti]; //Riempimento delle suddette strutture for(int e=1; e<=num_sedie; e++){ String nome_sedia = "sedia" + e; Sedia sedia = new Sedia(nome_sedia,"libera"); array_sedie[e-1] = sedia; } for(int d=1; d<=num_partecipanti; d++){ String nome_partecipante = "persona" + d; array_partecipanti[d-1] = nome_partecipante; } } public synchronized int getNumPartecipanti(){ return num_partecipanti; } public synchronized int getNumSedie(){ return num_sedie; } public synchronized int getNumSessioni(){ return num_sessioni; } public synchronized void setNumPartecipanti(int n){ num_partecipanti = n; } public synchronized void setNumSedie(int n){ num_sedie = n; } public synchronized void setNumSessioni(int n){ num_sessioni = n; } public synchronized void run(){ System.out.println("a"); try{wait();} catch(InterruptedException e){System.out.println(array_sedie.length);} System.out.println(array_sedie.length); int f = 0; while(f<array_sedie.length){ if(array_sedie[f].getStato()=="libera"){array_sedie[f].occupaSedia(); System.out.println(array_partecipanti[f]); array_sedie[f].setNameOccupante(array_partecipanti[f]); f++;} else f++; } notifyAll(); } public synchronized void metodo(){ int i = 1; //Ciclo Sessione while(i<=num_sessioni){ x = 0; System.out.println("Sessione: " + i); //Ciclo creazione Thread while(x<num_partecipanti){ runner = new OccupaSedia(num_sedie, num_partecipanti, num_sessioni); runner.start(); x++; } obj="vai"; notifyAll(); i++; //Stampa dei risultati di Sessione int g=0; while(g<array_sedie.length){ System.out.println(array_sedie[g].nome); System.out.println(array_sedie[g].getNameOccupante()); g++; } } } } Praticamente il metodo "metodo" ancia n thread che si devono bloccare finchè non arriva la notifica che tutti i thread sono stati creati in modo che eseguano il codice a partire dallo stesso momento. Ma quando incontrano la wait si blocca e non va avanti... |
![]() |
![]() |
![]() |
#2 |
Junior Member
Iscritto dal: Apr 2006
Città: avellino
Messaggi: 3
|
sono alle prese con lo stesso esercizio...ma sono più in panne di te! per caso sei riuscito a far qualcos'altro?
|
![]() |
![]() |
![]() |
#3 |
Senior Member
Iscritto dal: Mar 2004
Città: castel san giorgio(salerno)
Messaggi: 1218
|
Cosa bisogna fare per campare...
Anche tu vittima di Polese?
|
![]() |
![]() |
![]() |
#4 |
Junior Member
Iscritto dal: Apr 2006
Città: avellino
Messaggi: 3
|
si, ma c'è da piangere!!!
|
![]() |
![]() |
![]() |
#5 |
Senior Member
Iscritto dal: Mar 2004
Città: castel san giorgio(salerno)
Messaggi: 1218
|
C'è da piangere soprattutto se pensi che fare questo esercizio di merda si deve ricorrere al forum...
|
![]() |
![]() |
![]() |
#6 |
Junior Member
Iscritto dal: Apr 2006
Città: avellino
Messaggi: 3
|
si, e nonostante tutto cmq quel poco ke ho fatto non è nemmeno funzionante!!!
![]() |
![]() |
![]() |
![]() |
#7 |
Senior Member
Iscritto dal: Nov 2005
Città: Texas
Messaggi: 1722
|
Ciao,
ho letto la spiegazione, ed il codice sembra riportare quello che e' stato descritto. Pertanto, e' normale che i thread si blocchino sulla wait(), e' fatta apposta per quello: resteranno bloccati li' fintanto che qualcuno non li "risveglia" con una notify(). Nel codice ci sono due notifyAll(), candidate a risvegliare i thread: una e' posta nel metodo run(), quindi e' fuori gioco (inizialmente, intendo). L'altra e' nel metodo "metodo" (Ps se fosse stato scelto un altro nome, magari indicante quello che il metodo deve fare, avreste ottenuto aiuto piu' in fretta). Ma... chi chiama "metodo"? Il codice e' tutto qui? Non e' ovviamente possibile, questo codice e' solo un pezzettino, giusto? Una volta eseguita la creazione, questo metodo deve farli partire. Occorre controllare (eventualmente postare) il programma principale, per verificare questa se "metodo" e' chiamato correttamente. High Flying Sottovento
__________________
In God we trust; all others bring data |
![]() |
![]() |
![]() |
#8 |
Senior Member
Iscritto dal: Nov 2004
Città: Salerno
Messaggi: 842
|
Ecco la traccia:
Corstuire un programma in linguaggio java che, attraverso l’uso dei thread e della mutua esclusione, realizza il gioco Occupa-Sedia. Il gioco consiste nell’avere un certo numero K di sedie ed un numero N di persone con N>K ed un arbitro. Quando l’arbitro da il via le N persone partono contemporaneamente da una stessa posizione e cercano di occupare una sedia. Dopo ogni sessione del gioco, solo le K persone che sono riuscite a sedersi ricevono un punto. In pratica, occorre definire una classe Sedia per modellare un oggetto sedia che può trovarsi in due possibili stati: libera o occupata. I metodi di tale classe devono consentire di rilevare lo stato della sedia, di occuparla e di conoscere il nome dell’eventuale occupante. Occorre inoltre definire una classe Occupa-Sedia con attributi per rappresentare il numero di partecipanti, il numero di sedie disponibili ed il numero di sessioni previste per una determinata istanza del gioco. Occorre definire una struttura dati per modellare la sequenza di K sedie disponibili ed una per modellare gli N partecipanti al gioco. Sia le sedie che le persone devono essere identificabili tramite un nome (si può usare anche un sequenziale sedia1, sedia2, …, persona1, persona2,…). Il metodo main dovrà creare un’istanza del gioco, chiedendo all’utente di fornire in input i parametri della stessa (N, K ed il numero di sessioni) ed avviare il gioco. Il tentativo da parte delle N persone di occupare ciascuno una sedia dovrà essere modellato tramite N Thread e tutti dovranno (in teoria) essere avviati “contemporaneamente” (suggerimento: si potrebbero usare wait e NotifyAll). L’accesso dei thread alla struttura dati che modella la sequenza di sedie dovrà essere gestito in modo mutuamente esclusivo, attraverso l’uso di meccanismi di sincronizzazione. Il risultato finale dovrà consistere nella stampa dei risultati delle varie sessioni di un’istanza del gioco (indicando da chi è occupata ciascuna sedia) unitamente alla classifica finale con i punteggi riportati da ciascuna persona (numero di volte in cui è riuscito a sedersi). |
![]() |
![]() |
![]() |
#9 |
Senior Member
Iscritto dal: Mar 2004
Città: castel san giorgio(salerno)
Messaggi: 1218
|
Questo è un Thread contro Polese!!!
|
![]() |
![]() |
![]() |
#10 |
Senior Member
Iscritto dal: Mar 2004
Città: castel san giorgio(salerno)
Messaggi: 1218
|
import java.lang.InterruptedException;
public class OccupaSedia extends Thread{ public int num_persone; public int num_sedie; public int num_sessioni; public int persona_corrente; public Sedia[] array_sedie; public String array_persone[]; public Thread runner; public Object obj="a"; int x = 0; int h; public OccupaSedia(int a, int b, int c,int pcurr){ num_persone = b; num_sedie = a; num_sessioni = c; persona_corrente = pcurr; //Creazione struttura per sedie e partecipanti array_sedie = new Sedia[num_sedie]; array_persone = new String[num_persone]; //Riempimento delle suddette strutture for(int e=1; e<=num_sedie; e++){ String nome_sedia = "sedia" + e; Sedia sedia = new Sedia(nome_sedia,"libera"); array_sedie[e-1] = sedia; } for(int d=1; d<=num_persone; d++){ String nome_persona = "persona" + d; array_persone[d-1] = nome_persona; } } public synchronized int getNumPersone(){ return num_persone; } public synchronized int getNumSedie(){ return num_sedie; } public synchronized int getNumSessioni(){ return num_sessioni; } public synchronized void setNumPersone(int n){ num_persone = n; } public synchronized void setPersonaCorrente(int n){ persona_corrente = n; } public synchronized void setNumSedie(int n){ num_sedie = n; } public synchronized void setNumSessioni(int n){ num_sessioni = n; } public synchronized void run(){ while(obj=="vai"){ try{wait();} catch(InterruptedException e){} } int f = 0; while(f<array_sedie.length){ if(array_sedie[f].getStato()=="libera"){array_sedie[f].occupaSedia(); array_sedie[f].setNameOccupante(array_persone[persona_corrente]); break;} else f++; } } public synchronized void metodo(){ int[] punteggi = new int[num_persone]; for(int m=1; m<=num_persone; m++){ punteggi[m-1] = 0; } int i = 1; //Ciclo Sessione while(i<=num_sessioni){ x = 0; System.out.println("Risultati della giornata numero " + i); //Ciclo creazione Threads while(x<num_persone){ OccupaSedia s = this; s.setPersonaCorrente(x); runner = s; runner.start(); x++; } notifyAll(); i++; //Stampa dei risultati di Sessione int g=0; while(g<array_sedie.length){ System.out.println(array_sedie[g].nome + " occupata da " + array_sedie[g].getNameOccupante()); String aa = array_sedie[g].getNameOccupante().substring(array_sedie[g].getNameOccupante().length()-1,array_sedie[g].getNameOccupante().length()); int n = Integer.parseInt(aa); n--; punteggi[n]++; g++; } System.out.println(""); } System.out.println(""); System.out.println("Classifica finale del tredicesimo campionato mondiale del gioco della seggiola:"); while(h<array_persone.length){ System.out.println(array_persone[h] + " " + punteggi[h]); h++; } } } Questo è il mio codice. Questo pezzo: while(x<num_persone){ OccupaSedia s = this; s.setPersonaCorrente(x); runner = s; runner.start(); x++; } dovrebbe lanciare un numero pari a num_persone thread del tipo OccupaSedia. Il metodo run fa in modo che quando il thread è avviato va in attesa e riprende solo quando sono stati avviati tutti i thread. Grazie alla notifyAll() che c'è dopo il while. Purtroppo mi lancia IllegalStateException. Qualcuno sa perchè? Dovrebbe essere lanciata perchè il metodo start è invocato su un thread gia avviato, ma non era mia intenzione invocarlo sullo stesso thread bensi su uno diverso. Nel main viene chiamato metodo(Scusate in nome ma ho il fiato sul collo della consegna alle 15:00 e ho messo il primo nome che mi veniva in mente). |
![]() |
![]() |
![]() |
#11 |
Senior Member
Iscritto dal: Mar 2004
Città: castel san giorgio(salerno)
Messaggi: 1218
|
Ho la certezza ke ogni volta ke entro in run il nomedel thread ke ci entra è "thread-2". Questo vuol dire che sto creando sempre lo stesso thread o è normale?
|
![]() |
![]() |
![]() |
#12 |
Senior Member
Iscritto dal: Mar 2004
Città: castel san giorgio(salerno)
Messaggi: 1218
|
Vi do anche la classe Sedia e il main.
Sedia: public class Sedia { public String stato; public String occupante = ""; public String nome; public Sedia(String n, String s){ nome = n; stato = s; } public synchronized String getStato(){ return stato; } public synchronized void occupaSedia(){ stato = "occupata"; } public synchronized String getNameOccupante(){ return occupante; } public synchronized void setNameOccupante(String s){ occupante = s; } } Main: import java.io.*; import java.io.IOException; import javax.swing.JOptionPane; class test { public static void main(String[] args) { Object a="1"; //Inserimento dei dati di gioco ![]() String num_persone = JOptionPane.showInputDialog("Inserisci il numero di persone:"); String num_sedie = JOptionPane.showInputDialog("Inserisci il numero di sedie:"); String num_sessioni = JOptionPane.showInputDialog("Inserisci il numero di sessioni:"); int persone = Integer.parseInt(num_persone); int sedie = Integer.parseInt(num_sedie); int sessioni = Integer.parseInt(num_sessioni); int pers = 0; //Creazione di una istanza del gioco OccupaSedia gioco = new OccupaSedia(sedie,persone,sessioni,pers); gioco.metodo(); } } |
![]() |
![]() |
![]() |
#13 |
Senior Member
Iscritto dal: Feb 2005
Città: Napoli (provincia)
Messaggi: 2363
|
Cavolo vedo che Polese si è divertito
![]()
__________________
|
![]() |
![]() |
![]() |
#14 |
Senior Member
Iscritto dal: Mar 2004
Città: castel san giorgio(salerno)
Messaggi: 1218
|
Vedo che la fama di Mister Polese è molto conosciuta...
|
![]() |
![]() |
![]() |
#15 |
Senior Member
Iscritto dal: Feb 2005
Città: Napoli (provincia)
Messaggi: 2363
|
Mah l'ho avuto solo per LP2 e non posso lamentarmene più di tanto... Però ammetto che la sua capacità di criptare il testo di una traccia fino a renderlo incomprensibile è notevole
![]() Mi dispiace di non potervi aiutare nei thread, col Java me la cavo ma non li ho fatti ancora... Ciao a tutti!
__________________
|
![]() |
![]() |
![]() |
#16 |
Senior Member
Iscritto dal: Nov 2005
Città: Texas
Messaggi: 1722
|
Ciao,
ho dato un'occhiata veloce veloce al tuo codice: hai un illegal state exception perche' cerchi di lanciare (n volte) lo stesso thread, il quale sta gia' girando. Quindi ti risponde che lo stato non e' quello corretto. Ci sono anche un paio di cose strane: dichiari un oggetto "obj", il quale dovrebbe essere, secondo le intenzioni che ho evinto dal codice, l'oggetto sul quale effettui le sincronizzazioni e poi non lo valorizzi se non in inizializzazione. Inoltre il confronto fra stringhe non si fa con == (o meglio, questo operatore ha un altro significato rispetto a quello che volevi fare). Dopo, se il tempo non e' cosi' tiranno, do un'occhiata in maniera piu' approfondita... High Flying Sottovento
__________________
In God we trust; all others bring data |
![]() |
![]() |
![]() |
#17 |
Senior Member
Iscritto dal: Nov 2005
Città: Texas
Messaggi: 1722
|
Ciao,
scusa il ritardo ma sono piuttosto impegnato. Ho avuto poco tempo di guardare il codice, per cui ho potuto fare delle modifiche parziali. Secondo me, e' piu' logico introdurre un thread "Persona", che implementa il giocatore. Ho fatto queste modifiche (e pochi test, ad esser sincero). Spero che questo sia una traccia per completare il lavoro. Mi spiace non poterti dare qualcosa di completo. Le cose da fare ancora sono: - Sincronizzazione in terminazione (il thread principale deve andare a leggere la classifica solo quando tutti hanno terminato); - Rendere la ricerca del posto sincronizzata (il thread non puo' e non deve essere interrotto nel tempo che passa fra il controllo della seggiola vuota e la sua occupazione. E' molto importante! Per fortuna e' semplice da fare...). Il codice e' il tuo, con qualche piccola modifica ed un sacco di println () per controllo. Ci sono anche dei ritardi, li puoi eliminare quando hai risolto i punti di cui sopra High Flying Sottovento Codice:
import java.lang.InterruptedException; class Persona extends Thread { private Object objStart; private Sedia[] array_sedie; private String name; private int score; private boolean done; public Persona (String name, Object objStart, Sedia[] array_sedie) { this.name = name; this.objStart = objStart; this.array_sedie = array_sedie; this.score = 0; this.done = false; start (); } public void run() { if (objStart == null) { System.out.println ("Programming error - Start object is null"); System.exit (0); } while(!done) { try { synchronized (objStart) { System.out.println (name + " in wait"); objStart.wait(); System.out.println (name + " svegliato"); } } catch(InterruptedException e) { System.out.println ("Exception in wait: " + e); // Downwind - added this for debug purposes e.printStackTrace (); // Downwind - added this for debug purposes } if (done) { System.out.println (name + " FINITO"); return; // we should finish application } System.out.println ("Persona " + name + " comincia a correre"); for (int i = 0; i < array_sedie.length; i++) { if (array_sedie[i].getStato().equals ("libera")) { System.out.println ("Persona " + name + " si prende la seggiola " + i); array_sedie[i].occupaSedia(); array_sedie[i].setNameOccupante(name); score++; System.out.println ("Punteggio corrente: " + score); break; } } } } public void finish () { synchronized (objStart) { done = true; } } public String getPlayerName () { return name; } public int getScore () { return score; } } public class OccupaSedia { public int num_persone; public int num_sedie; public int num_sessioni; public int persona_corrente; public Sedia[] array_sedie; public Object objStart; private Persona[] giocatori; public OccupaSedia(int a, int b, int c,int pcurr) { num_persone = b; num_sedie = a; num_sessioni = c; persona_corrente = pcurr; //Creazione struttura per sedie e partecipanti array_sedie = new Sedia[num_sedie]; //Riempimento delle suddette strutture for(int e = 1; e <= num_sedie; e++) { String nome_sedia = "sedia" + e; Sedia sedia = new Sedia(nome_sedia,"libera"); array_sedie[e-1] = sedia; } // Create objects and people objStart = new String ("vai"); giocatori = new Persona[num_persone]; for (int i = 0; i < num_persone; i++) giocatori[i] = new Persona ("giocatore" + (i + 1), objStart, array_sedie); } public int getNumPersone() { return num_persone; } public int getNumSedie() { return num_sedie; } public int getNumSessioni() { return num_sessioni; } public void setNumPersone(int n) { num_persone = n; } public void setPersonaCorrente(int n) { persona_corrente = n; } public void setNumSedie(int n) { num_sedie = n; } public void setNumSessioni(int n) { num_sessioni = n; } public synchronized void metodo() { // try // { // Thread.sleep (1000); // } // catch (Exception e) { } for (int sessione = 0; sessione < num_sessioni; sessione++) { // Ripristina le sedie a libere for (int g = 0; g<array_sedie.length; g++) array_sedie[g].setStato ("libera"); System.out.println("Risultati della giornata numero " + (sessione+1)); // Downwind - all threads are created. I can wake up them try { synchronized (objStart) { objStart.notifyAll(); } } catch (Exception e) { e.printStackTrace (); } try { Thread.sleep (1000); } catch (Exception e) { } //Stampa dei risultati di Sessione for (int g = 0; g<array_sedie.length; g++) System.out.println(array_sedie[g].getName() + " occupata da " + array_sedie[g].getNameOccupante()); System.out.println(); // Wait a few before next session try { Thread.sleep (3000); } catch (Exception e) { } } System.out.println(""); System.out.println("Classifica finale del tredicesimo campionato mondiale del gioco della seggiola:"); for (int h = 0; h < giocatori.length; h++) System.out.println(giocatori[h].getPlayerName() + " = " + giocatori[h].getScore()); try { Thread.sleep (3000); } catch (Exception e) { } System.out.println ("Notifico a tutti di fermarsi"); for (int i = 0; i < giocatori.length; i++) giocatori[i].finish(); synchronized (objStart) { objStart.notifyAll (); } } }
__________________
In God we trust; all others bring data |
![]() |
![]() |
![]() |
#18 |
Senior Member
Iscritto dal: Mar 2004
Città: castel san giorgio(salerno)
Messaggi: 1218
|
Alcuni miei colleghi l'hanno fatto simile al mio e si trovano. Vorrei cercare di aggiustare il meno possibile il mio codice. Praticamente dove lancio gli n thread dovrei cercare di lanciare thread diversi e non uguali, come posso fare?
Comunque fa niente se rispondi tardi. Fallo quando puoi, io aspetto, ormai giusto o sbagliato l'ho consegnato gia il lavoro. |
![]() |
![]() |
![]() |
#19 | |
Senior Member
Iscritto dal: Nov 2005
Città: Texas
Messaggi: 1722
|
Quote:
Intanto controlla una cosa: cosi' come fatto, il codice non puo' lanciare i thread che vuoi, ed e' questo il senso dell'eccezione che ti compariva. In pratica, hai creato un oggetto (il thread), quindi puoi fare un solo start. High Flying Sottovento
__________________
In God we trust; all others bring data |
|
![]() |
![]() |
![]() |
#20 |
Senior Member
Iscritto dal: Mar 2004
Città: castel san giorgio(salerno)
Messaggi: 1218
|
Ho capito il senso dell'eccezione.
Quindi, visto che il thread che vado a creare è sempre quello, come creo n thread? |
![]() |
![]() |
![]() |
Strumenti | |
|
|
Tutti gli orari sono GMT +1. Ora sono le: 03:09.