Newsgroup: it.comp.java
Titolo: Gestire la sincronizzazione tra thread

Devo risolvere un problema assillante, e non riesco a capire come 
implementare la cosa... parto con la spiegazione:
La mia applicazione è formata da 2 threads:
Il thread principale si occupa della interfaccia con l'utente e di mostrare 
i dati scaricati da un database.
Il secondo thread, avviato su richiesta dell'utente, si connette al database 
e scarica i dati: una volta avvenuto lo scaricamento chiama il thread 
principale e gli passa i dati scaricati.
Il problema in soldoni è che devo evitare assolutamente che parta una 
seconda chiamata al database quando la prima chiamata non è stata ancora 
terminata.
Ho creato quindi un metodo statico SYNCHRONIZED che si occupa di gestire lo 
scaricamento, e che viene chiamato dal thread principale quando deve 
connettersi al database:
questo metodo statico crea il thread secondario, lancia il thread... e qui 
viene il problema!
Una volta lanciato il thread il metodo esce, in quando è poi il thread a 
chiamare il listener appropriato, quindi la mia sincronizzazione di fatto 
così com'è è initile: per essere efficace dovrei aspettare che il thread 
finisca l'esecuzione del lavoro (questo posso farlo tramite un medodo 
isWorkCompleted del mio oggetto runnable), e solo a quel momento ritornare.
Ma io da un metodo statico come posso dire al monitor di mettersi in stato 
di wait, visto che wait() e notify() sono metodi di istanza di object?
Ho quindi creato un oggetto Connector, che in pratica fa quello che fa il 
metodo statico ma essendo di istanza posso chiamare wait() e notifyAll()... 
quando chiamo wait xò ottendo un "MonitorStateException...current thread not 
owner".
Come vedete ho le idee un pò confuse, e mi serve di capire come risolvere il 
mio problema di sincrozizzazione, o magari qualche esempio chiaro su come 
gestire la sincrozizzazione...
Grazie :) 

 isWorkCompleted del mio oggetto runnable), e solo a quel momento ritornare.
se ho capito bene, prova a usare join.
Altrimenti, posta un po' di codice (edulcorato dei dettagli, magari con
delle println che aiutino a capire l'ordine di esecuzione che ti aspetti)
hth,
uL
-- 
questo articolo e` stato inviato via web dal servizio gratuito 
http://www.newsland.it/news
 segnala gli abusi ad 
ab...@newsland.it

 uL
N
--------------------------------
Inviato via 
http://arianna.libero.it/usenet/

> delle println che aiutino a capire l'ordine di esecuzione che ti aspetti)
Posto uno pseudo codice che spero sia chiaro:
public class HttpDatabaseConnection implements Runnable
{
    // Costruttori privati in funzione dei listener:
 // L'istanziazione della classe avviene solo nel metodo statico, che chiamo 
dal mio codice
    private HttpDatabaseConnection(MainApp container, String sourcemdb, 
String query,
            FilterDownloadedListener filterDownloadedWaiter)
    {
        this(container, sourcemdb, query);
        this._filterDownloadedWaiter = filterDownloadedWaiter;
    }
    private HttpDatabaseConnection(MainApp container, String 
sourcemdb,String query,
            ThemesDownloadedListener themesDownloadedWaiter)
    {
        this(container, sourcemdb, query);
        this._themesDownloadedWaiter = themesDownloadedWaiter;
    }
    private HttpDatabaseConnection(MainApp container, String 
sourcemdb,String query,
            BandsInformationsDownloadedListener 
bandsInformationsDownloadedWaiter)
    {
        this(container, sourcemdb, query);
        this._bandsInformationsDownloadedWaiter = 
bandsInformationsDownloadedWaiter;
    }
    private HttpDatabaseConnection(MainApp container, String sourcemdb, 
String query, UsersDatabaseListener usersDatabaseWaiter)
    {
        this(container, sourcemdb, query);
        this._usersDatabaseWaiter = usersDatabaseWaiter;
    }
    private HttpDatabaseConnection(MainApp container, String sourcemdb, 
String query)
    {
        super();
        this._container = container;
        this._sourcemdb = sourcemdb;
        this._query = query;
    }
    public void start()
 {
     if(_t == null)
     {
         _t = new Thread(this);
         _t.start();
     }
 }
 public void stop()
 {
     if(_t.isAlive())
     {
         try
         {
             _t.join();
         }
         catch(Exception ex)
         {
             ex.printStackTrace();
         }
     }
     _t = null;
 }
 public void run()
 {
     try
     {
            // Step di connessione al database:
      this.openSession();  // 1: apertura della sessione
   this.openDatabaseConnection(); // 2: apertura connessione
   this.readDatabaseContent(); // 3: download informazioni
         this._errorVerified = false;
     }
  catch(Exception ex) //Eccezione generica, se si verifica un errore di 
connessione
  {
      this._errorVerified = true;
  }
  finally
  {
         this.closeDatabaseConnection(); //  4: chiusura connessione
         this.closeSession(); // 5: chiusura sessione
         // Lancio la risposta
         if(this._errorVerified)
             this.callListenersForError();
         else this.callListenersForResponse();
  }
 }
 private void callListenersForError()
 {
     // Chiamo i listener attivi e comunico l'errore nel download
    }
    private void callListenersForResponse()
    {
        System.err.println("Listener called for response");
        // Chiamo i listener attivi e passo le informazioni scaricate
    }
    // Apertura della sessione al database
 private boolean openSession()
 {
    // Procedure per l'apertura della sessione
 }
 // Apertura della connessione al database
 private boolean openDatabaseConnection()
 {
    // Procedure per la connessione al db
 }
 // Lettura del database
 private boolean readDatabaseContent()
 {
    // Lettura del db
 }
    // chiusura della connessione al database
 private boolean closeDatabaseConnection()
 {
     // Chiusura connessione al db
 }
 // Chiusura della sessione al database
 private boolean closeSession()
 {
    // Chiusura della sessione
 }
 public boolean isWorkCompleted()
 {
  return _t.isAlive();
 }
 // Metodo unico sincronizzato per ottenere le informazioni
 public static synchronized void getInformations(MainApp container, String 
sourcemdb, String query,
            Object listener, int listenerType)
 {
     try
     {
         // Istanzio un oggetto di tipo connection
         HttpDatabaseConnection conn = null;
         // Ciclo per impostare il listener
         switch(listenerType)
         {
          // Definisco i listeners
         }
         // Richiesta con thread di download
         conn.start();
   // Pseudocodice per l'attesa
   while(conn.isWorkCompleted())
   {
    try
    {
     wait(); // Metodo di istanza: non esiste statico
    }
    catch(Exception ex)
    {
    }
   }
   // Uscita dal metodo: dovrebbe avvenire dopo la chiamata a 
callListenersForResponse()
   notifyAll();
         System.out.println("method returned");
     }
     catch(Exception ex)
     {
         ex.printStackTrace();
     }
 }
 public void startWithoutThreadRequest()
 {
     run();
 }
}
Quando lancio il programma ad ogni connessione al db la console stampa 
SEMPRE:
"method returned"
"Listener called for response"
in quest'ordine, mentre dovrebbe avvenire il contrario.
Any idea?
Grazie per l'interesse comunque :)