11

我相信,在我的 JAVA GUI 中,我正在处理一个竞争条件。

我有一些方法可以在这样的匿名类中创建“匿名方法”:

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

               //stuff

          }
     };
}

问题:该运行方法是在 TimerTask 对象上同步还是在 foo 所在的类上同步?

QUESTION2:如果我去掉了 run() 声明中的“synchronized”,而是在 run() 主体内有一个 synchronized(this) {} 块,“this”是指 TimerTask 对象还是指是包含 foo() 的方法的实例吗?

请帮帮我。

谢谢,jbu

4

4 回答 4

14

run方法在TimerTask自身上同步。同步的实例方法总是this对象上同步。(类方法在Class对象上同步。)

如果要在其foo成员对象上进行同步,则需要限定this关键字。假设foo()Bar类的成员,在 的run()方法里面TimerTask,可以使用

public void run() {
  synchronized(Bar.this) {
    ...
  }
}
于 2009-04-30T22:49:38.393 回答
2

我很确定这些答案,但我无法找到一个好的来源 atm。

第一个问题:
synchronized会锁定TimerTask。

第二个问题:
this指的是TimerTask;如果您想锁定包含对象,请使用 MyContainingObject.this

于 2009-04-30T22:46:25.530 回答
1

只有一个线程可以访问摆动元素。那是 AWT-EventQueue-0。你需要意识到这一点。如果您的其他线程正在淹没或更改元素,则 gui 很可能会崩溃。用这个线程运行你的 gui:

  尝试 {
            SwingUtilities.invokeAndWait(new Runnable(){
                公共无效运行(){
                    Swing_Prozor1 prozor = 新 Swing_Prozor1();
                }
            });
        } 捕捉(InterruptedException e){
            //namjerno zanemareno
        } 捕捉(InvocationTargetException e){
            //namjerno zanemareno
        }

如果你有匿名类,这会给你你所在的类的实例,所以如果你在匿名类中写这个。是该类的实例。要获取您想要编写的类的实例:

类名.this

嗯,你写的上面的代码告诉我这一点。您两次保护了部分代码。当您编写同步方法时,这意味着一次只有一个线程可以访问该方法。其他线程在同步方法解锁时等待。

于 2009-04-30T23:14:12.547 回答
0

如果您正在寻找同步 foo() 和 run() 那么您可以创建一个显式锁定对象,例如

最终对象锁 = 新对象();

然后同步就可以了。

foo() {
    synchronized(lock) {
       someMethod(new TimerTask() {
          public void run() {
              synchronized(lock)  {
                     //stuff
              }
          }
      }
于 2009-05-01T11:35:53.950 回答