PDA

Visualizza la versione completa : [JAVA] Thread in Java


Teo Mala
20-10-2005, 14:25
Thread in java
Reply Quote

Ciao a tutti!
Ho un problema con la programmazione multithread : devo implementare un programma che crei un numero variabile di sottothread, ognuno dei quali acceda a delle risorse in maniera esclusiva (esiste un numero massimo settabile di 3d che possono accedere a ciascuna risorsa). In breve, devo realizzare una simulazione di un semaforo in java.
Ho quindi creato una serie di 3d estendo la classe Thread di Java, ampliandola con i metodi che mi interessavano; un'altra classe si occupava, invece, di gestire i conflitti per le risorse (in pratica costituisce il semaforo).
Il problema è che non riesco a mettere in wait i 3d quando la risorsa è occupata. Ho provato a usare le funzioni suspend(), stop(), brakes() (chiamandole dall'interno del 3d da sospendere) e il metodo wait(), sia dall'interno del 3d da sospendere, sia chiamandolo dal controllore esterno (dal 3d semaforo. In questo caso ottenevo il 3d t da mettere in wait e poi facevo t.wait(), ottendo però la seguente eccezione: "Exception in thread "AWT-EventQueue-0" java.lang.IllegalMonitorStateException: current thread not owner"). In tutti i casi non raggiungevo il risultato ottenuto, o perchè il 3d non si sospendeva (usando suspend() e stop()), o perchè non si bloccava solo il 3d desiderato, ma l'intera applicazione (con wait()).
Posto parte del codice della classe thread, nel caso fosse utile per individuare il problema:



public class UserThread extends Thread {

private DataContrInterface dc;
private int name;
private Vector usedResources;
private Vector resInQueue;

public UserThread(){
System.out.println("Creato nuovo User3d !!!");
}

public UserThread(int name, DataContrInterface dc){
this.name = name;
this.dc = dc;
this.usedResources = new Vector();
this.resInQueue = new Vector();
System.out.println("Creato nuovo User3d !!!");
}
.
.
.
public synchronized void brakes(int resId)
{

if (this.isInterrupted()==false)
{
this.resInQueue.add(Integer.toString(resId));
//try

//this.wait();
this.suspend();


/*catch (InterruptedException exc) {
System.out.println(this.getName()+": i'm waiting");
exc.getStackTrace();
}*/
MessageWindow w = new MessageWindow(100,100,"ATTENZIONE!","3d "+resId+ " NON sospeso!!!!");
System.out.println("**************3d "+resId+ " NON sospeso!!!!***************");
}
else
{
System.out.println("CIAO");
}

}


L'effetto ottenuto usando wait() (si blocca l'intera applicazione, non solo un 3d), mi fa pensare che forse il programma non sia in realtà multithread, ma instanziando più volte una classe che estende la classe Thread non dovrei ottenere più 3d concorrenti come desiderato???
Chiedo scusa nel caso la domanda risultasse banale, ma sono bloccato su questo punto da tempo e forse qualcuno saprà aiutarmi.
Grazie mille anticipatamente per l'aiuto!!!
Ciao!!!!
:bhò: :dhò: :dhò: :dhò: :dhò: :dhò: :dhò: :dhò:

LeleFT
20-10-2005, 14:37
Dunque.
A te serve una classe che estende Thread che rappresenta il thread che accede alla risorsa e una classe che rappresenta il "semaforo" che fa accedere il thread alla risorsa.

La classe che estende Thread deve occuparsi solo del lavoro che essa deve svolgere: accedere alla risorsa. Non si deve preoccupare di fermarsi o riattivarsi, a questo ci pensa il semaforo:


public class MioThread extends Thread {
public MioThread(...) { ... }
public void run() {
// esegue le proprie azioni sulla risorsa
risorsa.accedi();
}
}

La classe che rappresenta il semaforo per la risorsa, invece, deve prevedere dei metodi per l'accesso da parte dei thread: saranno questi che controllano la fattibilità dell'operazione e, eventualmente, fermano il thread che ha fatto la richiesta:


public class Risorsa {
public synchronized void accedi() {
try {
while (condizione_di_non_accesso) wait();
... // accesso alla risorsa
notifyAll(); // Notifico a tutti che la risorsa è disponibile
} catch (Exception e) { e.printStackTrace();}
}
}

Come sbloccare i thread dipende dall'applicazione. Se ad esempio ho una situazione di tipo Produttore/Consumatore l'accesso alla risorsa sarà effettuato da due Thread di tipo diverso tramite due metodi diversi. Sarà il metodo di accesso al produttore che sbloccherà i consumatori, ponendo la condizione_di_non_accesso (al consumatore) a false e richiamando notifyAll(). Viceversa, sarà il metodo di accesso al consumatore che sbloccherà il produttore ponendo la condizione di non accesso (al produttore) a false e richiamando notifyAll().


Ciao. :ciauz:

Loading