Domanda

Ho a che fare con una condizione di gara, credo, nella mia GUI di JAVA.

Ho alcuni metodi che creano un "metodo anonimo" all'interno di una classe anonima come questa:

synchronized foo()
{
     someMethod(new TimerTask()
     {
          public synchronized run()
          {

               //stuff

          }
     };
}

DOMANDA: quel metodo di esecuzione è sincronizzato sull'oggetto TimerTask o sulla classe in cui si trova foo?

DOMANDA2: se mi sbarazzassi di " sincronizzato " nella dichiarazione run () e invece avere un blocco (this) {} sincronizzato all'interno del corpo run (), sarebbe " questo " fare riferimento all'oggetto TimerTask o all'oggetto che è un'istanza del metodo che contiene foo ()?

Per favore, aiutatemi qui.

Grazie, JBU

È stato utile?

Soluzione

Il metodo esegui è sincronizzato sul TimerTask stesso. I metodi di istanza sincronizzati sono sempre sincronizzato su questo oggetto. (I metodi di classe sono sincronizzati sull'oggetto Class .)

Se desideri sincronizzare l'oggetto di cui foo è un membro, devi qualifica la parola chiave this . Supponi che foo () sia un membro di < code> Bar , all'interno del metodo run () di TimerTask , puoi usare

public void run() {
  synchronized(Bar.this) {
    ...
  }
}

Altri suggerimenti

Sono abbastanza sicuro di queste risposte, ma non riesco a trovare una buona fonte atm.

La prima domanda:
sincronizzato bloccherà TimerTask.

Seconda domanda:
questo si riferisce al TimerTask; se volessi bloccare l'oggetto contenente, useresti MyContainObject.this

Esiste un solo thread che può avere accesso agli elementi swing. Questo è AWT-EventQueue-0. Devi esserne consapevole. Se altri dei tuoi thread stanno assottigliando o cambiando elementi, è molto probabile che la gui si blocchi. Per eseguire la tua interfaccia grafica con questo thread:

  try {
            SwingUtilities.invokeAndWait(new Runnable(){
                public void run(){
                    Swing_Prozor1 prozor = new Swing_Prozor1();
                }
            });
        } catch (InterruptedException e) {
            //namjerno zanemareno
        } catch (InvocationTargetException e) {
            //namjerno zanemareno
        }

e se hai delle classi anonime, questo ti darà un'istanza della classe in cui ti trovi, quindi se stai scrivendo in una classe anonima questo. è un'istanza di quella classe. Per ottenere l'istanza della classe che vuoi scrivere:

  

ClassName.this

hmm questo codice sopra che hai scritto mi dice questo. Hai preteso due volte parte del codice. Quando si scrive un metodo sincronizzato significa che solo un thread può accedere a questo metodo alla volta. Altri thread attendono che il metodo sincronizzato sia sbloccato.

Se stai cercando di sincronizzare foo () ed run (), puoi creare un oggetto lock esplicito come

final Object lock = new Object ();

e quindi sincronizzare su di esso.

foo() {
    synchronized(lock) {
       someMethod(new TimerTask() {
          public void run() {
              synchronized(lock)  {
                     //stuff
              }
          }
      }
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top