2009-04-30 17 views
10

Estoy lidiando con una condición de carrera, creo, en mi GUI de JAVA.clases y sincronización anónimas de Java y "esto"

tengo algunos métodos que crean un "método anónimo" dentro de una clase anónima como esto:

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

       //stuff 

      } 
    }; 
} 

pregunta: ¿Es ese método de ejecución sincronizada en el objeto TimerTask o la clase que foo es en?

PREGUNTA2: si eliminé el "sincronizado" en la declaración run(), y en su lugar tengo un bloque sincronizado (this) {} dentro del cuerpo run(), "this" se referiría al objeto TimerTask o al objeto que es una instancia del método que contiene foo()?

Por favor, ayúdenme aquí.

Gracias, JBU

+0

Esto es un error que incluso aparece en el libro de Java Concurrency In Practice (JCiP). Es una pena que Java esté tan débilmente tipeado con respecto a sincronizado. –

Respuesta

13

El método run está sincronizado en el TimerTask. Objeto sincronizado instance methods are always synchronized on this. (Los métodos de clase se sincronizan en el objeto Class.)

Si desea sincronizar en el objeto de los cuales foo es un miembro, es necesario qualify the this keyword. Supongamos foo() es un miembro de la clase Bar, dentro del método de TimerTaskrun() , puede usar

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

"Los métodos sincronizados siempre están sincronizados en este objeto". -Es difícil distinguir qué objeto es ESTO en este caso. ¿Es siempre la clase más interna/más cercana? – jbu

+0

Sí, creo que podría decirlo de esa manera. Es la instancia de la cual el método es miembro. run() es un miembro de TimerTask anónimo; foo() es un miembro de la instancia adjunta. – erickson

+0

Sería más divertido si tuviéramos cierres BGGA. esto se referiría a la clase interna en cierres tradicionales (limitados), pero la clase externa en cierres BGGA (más completos). –

2

estoy bastante seguro de estas respuestas, pero no se puede sacar una buena fuente atm.

La primera pregunta:
sincronizada se bloqueará en el TimerTask.

Segunda pregunta:
esto se refiere a TimerTask; si desea bloquear el objeto que contiene, debe usar MyContainingObject.this

1

Solo hay un hilo que puede tener acceso a los elementos de giro. Eso es AWT-EventQueue-0. Debes ser consciente de esto Si otros de tus hilos se están ahogando o cambiando elementos, hay una gran probabilidad de que la interfaz gráfica se bloquee. para hacer funcionar su interfaz gráfica de usuario con este tema:

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

y si tiene clases anonymus esto le dará instancia de la clase en la que se encuentre, por lo que si usted está en la clase writteing Anonymus esto. es instancia de esa clase. Para llegar instancia de clase que desea escribir:

ClassName.this

hmm este código que escribiste me dice esto. Pretectó parte del código dos veces. Cuando escribe un método sincronizado, significa que solo un hilo puede acceder a este método a la vez. Otros subprocesos esperan mientras el método sincronizado está desbloqueado.

0

Si usted está buscando para la sincronización del foo() y ejecutar() entonces puede crear un objeto de bloqueo explícita como

cerradura objeto final = new Object();

y luego sincronizar en él.

foo() { 
    synchronized(lock) { 
     someMethod(new TimerTask() { 
      public void run() { 
       synchronized(lock) { 
        //stuff 
       } 
      } 
     } 
Cuestiones relacionadas