Domanda

Sto usando più thread nella mia applicazione. Fondamentalmente ho una casella combinata e dopo aver selezionato la posta in arrivo, P1 riprende e P2 viene sospeso e dopo la selezione di invio, p2 avvia e p1 si fermano. Di seguito è riportato il codice (sono sicuro che non è perfetto)

public void modifyText(ModifyEvent e) {
                if (combo.getText().equals("Inbox"))
                {
                    synchronized(p2) 
                    {
                        p2.cont = false;
                    }
                    table.removeAll();
                    synchronized(p1)
                    {
                        p1.cont = true;
                        p1.notify();
                    }
                }


                else if (combo.getText().equals("Sent"))
                {
                    synchronized(p2) 
                    {
                        p1.cont = false;
                    }
                    table.removeAll();
                    synchronized(p1)
                    {
                        p2.cont = true;
                        p2.notify();
                    }
                }
            }
        });

E per P1 e P2 ho questo all'interno dei loro loop:

synchronized (this) {
            while (cont == false)
                try {
                    wait();
                } catch (Exception e) {
                }
        } 

... come è ora funziona (sono un principiante per i fili). Durante la pressatura inviata nella scatola combinata, ottengo unastatemonitorexception illegale. Qualcuno potrebbe aiutarmi a risolvere il problema per favore?

Grazie e saluti, krt_malta

È stato utile?

Soluzione

Il problema è qui:

synchronized(p1)
{
    p2.cont = true;
    p2.notify();
}

Stai facendo p2.notify() Quando non hai un blocco p2 (È necessario tenere il monitor per chiamare Notify su di esso). Modificare synchronized(p1) a synchronized(p2). Inoltre, è necessario invertire anche l'altra clausola sincronizzata che è anche difettosa. Quindi, come esempio:

synchronized(p1) 
{
    p1.cont = false;
    // p1.notify(); <- do you need this here?
}
table.removeAll();
synchronized(p2)
{
    p2.cont = true;
    p2.notify();
}

Inoltre, anche il tuo altro codice è un po 'sbagliato, è una pessima pratica bloccare all'interno di un intero anello, renderlo un po' più atomico.

while (!cont) {
    synchronized (this) {
       try {
           wait();
       } catch (Exception e) {
       }
    }
}

Ulteriore ottimizzazione, evitare synchronised se possibile:

if (p1.cont) {
   synchronized(p1) 
   {
       p1.cont = false;
       // p1.notify(); <- do you need this here?
   }
}
table.removeAll();

if (!p2.cont) {
   synchronized(p2)
   {
       p2.cont = true;
       p2.notify();
   }
}

Crea il campo Cont volatile Qui, e rispecchiati per l'altra parte dell'istruzione IF, come appropriato.

EDIT: Guardando indietro a questo e combattendo con un bug di concorrenza che stavo affrontando di recente, chiunque implementasse questo modello potrebbe affrontare un problema con un'attesa infinita, se un oggetto è bloccato e mezza bloccato viene esaminato dal condizionale del tempo Loop (questo perché esiste un divario in cui lo stato può cambiare tra la valutazione del condizionale e l'imposizione della dichiarazione di attesa). In questo caso, posizionare il blocco sincronizzato sul fuori del ciclo.

Altri suggerimenti

In questo codice

                synchronized(p1)
                {
                    p2.cont = true;
                    p2.notify();
                }

Stai sincronizzando p1 Ma chiamando notify() Su p2, il che porta all'eccezione.

Non puoi aspettare nel thread di spedizione di eventi AWT, altrimenti che reggerà l'intera app. Leggi http://en.wikipedia.org/wiki/event_dispatching_thread

Inoltre non dovresti usare i thread grezzi a meno che tu non sappia davvero cosa stai facendo. Guardare http://java.sun.com/javase/6/docs/api/java/util/concurrent/package-summary.html e leggi Esecutori

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top