2009-04-30 66 views
10

我正在處理競爭條件,我相信,在我的JAVA GUI中。java匿名類和同步和「this」

我有一個創建一個匿名內部類這樣的「匿名方法」的一些方法:

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

       //stuff 

      } 
    }; 
} 

問題:是對TimerTask的對象或類foo是在同步該運行方法?問題2:如果我在run()聲明中刪除了「synchronized」,並且在run()體內部有一個synchronized(this){}塊,則「this」會引用TimerTask對象,或者對象是包含foo()的方法的一個實例?

請幫我看看這裏。

感謝, JBU

+0

這是一個錯誤,甚至出現在Java併發實踐(JCiP)書中。很遺憾,Java在同步方面很弱。 – 2009-04-30 23:12:28

回答

13

run方法在TimerTask本身上同步。同步instance methods are always synchronized on this對象。 (類的方法是本Class對象上同步。)

如果要其foo是其成員的對象同步,則需要qualify the this keyword.假設foo()Bar類的一個成員,的TimerTaskrun()方法內,你可以使用

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

「同步方法始終在此對象上同步。」 - 在這種情況下很難區分哪一個對象。它總是隻是最裏面/最近的班級嗎? – jbu 2009-04-30 22:52:08

2

我敢肯定,這些問題的答案,但我不能挖了一個很好的來源大氣壓。

第一個問題:
synchronized會鎖定TimerTask。

第二個問題:
這是指TimerTask;如果您想鎖定包含對象,請使用MyContainingObject.this

1

只有一個線程可以訪問swing元素。這就是AWT-EventQueue-0。你需要知道這一點。如果你的其他線程正在尋找或改變元素,那麼gui會很有可能崩潰。 要使用這個線程運行GUI:

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

,如果你有anonymus類這會給你在你的類的實例,因此,如果您在anonymus類此writteing。是該類的實例。要獲取類的實例你想要寫:

ClassName.this

嗯,你寫了這上面的代碼告訴我這一點。您預先檢測了部分代碼兩次。 當您編寫syncronized方法時,意味着一次只有一個線程可以訪問此方法。其他線程等待syncronized方法解鎖。

0

如果您正在尋找同步,把foo()和run(),那麼您可以創建像

明確鎖定對象

最終目標鎖定=新的對象();

然後對其進行同步。

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