Reputation: 16161
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 1: is that run method synchronized on the TimerTask object or the class that foo is in?
QUESTION 2: 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()?
Upvotes: 11
Views: 6203
Reputation: 374
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
}
}
}
Upvotes: 0
Reputation: 333
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.
Upvotes: 1
Reputation: 269837
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) {
...
}
}
Upvotes: 14
Reputation: 22601
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
Upvotes: 2