views:

808

answers:

4

hi all,

I am dealing with a race condition, I believe, in my JAVA GUI.

I have some methods that create an "anonymous method" inside an anonymous class like this:

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

               //stuff

          }
     };
}

QUESTION: is that run method synchronized on the TimerTask object or the class that foo is in?

QUESTION2: if I got rid of the "synchronized" in the run() declaration, and instead have a synchronized(this) {} block inside the run() body, would "this" refer to the TimerTask object or to the object that is an instance of the method that contains foo()?

Please help me out here.

Thanks, jbu

+2  A: 

I'm pretty sure of these answers, but I can't dig up a good source atm.

The first question:
synchronized will lock on the TimerTask.

Second question:
this refers to the TimerTask; if you wanted to lock on the containing object you'd use MyContainingObject.this

Kevin Montrose
+6  A: 

The run method is synchronized on the TimerTask itself. Synchronized instance methods are always synchronized on this object. (Class methods are synchronized on the Class object.)

If you want to synchronize on the object of which foo is a member, you need to qualify the this keyword. Suppose foo() is a member of the Bar class, inside the run() method of TimerTask, you can use

public void run() {
  synchronized(Bar.this) {
    ...
  }
}
erickson
"Synchronized methods are always synchronized on this object."-It is hard to distinguish which object is THIS in this case. Is it always just the innermost/nearest class?
jbu
Yes, I think you could put it that way. It is the instance of which the method is a member. run() is a member of the anonymous TimerTask; foo() is a member of the enclosing instance.
erickson
It would be more fun if we had BGGA closures. this would refer to the inner class in traditional (limited) closures, but the outer class in BGGA (more complete) closures.
Tom Hawtin - tackline
If you precede "this" with the class name, any perceived ambiguity will be resolved.
Caffeine Coma
+1  A: 

There is only one thread that can have access to swing elements. Thats AWT-EventQueue-0. You need to be aware of this. If other of your threads are drowing or changeing elements there is very good probability that gui will crash. To run your gui with this 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
     }

and if you have anonymus classes this will give you instance of class in which you are, so if you are writteing in anonymus class this. is instance of that class. To get instance of class you want write:

ClassName.this

hmm this above code you wrote tells me this. You pretected part of the code twice. When you write syncronized method it means that only one thread can access this method at one time. Other threads waits while syncronized method is unlocked.

shake
A: 

If you are looking for synchronizing the foo() and run() then you may create an explicit lock object like

final Object lock = new Object();

and then synchronize on it.

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