2014-01-27 74 views
2

:。呼叫PlatformUI.getWorkbench()getDisplay()syncExec從我所看到的UI線程

if (Display.getCurrent() == null){ 
    PlatformUI.getWorkbench().getDisplay.asyncExec(aRunnable) 
} else { 
    aRunnable.run(); 
} 

我不知道它是否真的需要手動檢查當前執行線程。如果我無條件使用

PlatformUI.getWorkbench().getDisplay.asyncExec(aRunnable) 

不會顯示實現處理這兩種情況正確嗎?如果是這樣,當asyncExec替換爲syncExec時,它是否也能正確處理?

回答

2

這是一個實現細節,當從UI線程調用時,如何操作syncExecasyncExecdocumentation指出:

導致runnable的run()方法在下一個合理機會被用戶界面線程調用。

這意味着你的Runnable可以簡單地把在隊列中,執行下一個調度循環,可能落後於其他Runnable秒。如果您在UI線程上專門調用Runnablerun方法,則可以更好地控制其調度。

當然,從UI線程調用時,syncExecasyncExec的行爲可能會有所不同。我似乎記得syncExec將在從UI線程調用時立即執行,並且asyncExec將始終將其工作排隊,但這又是一個實現細節,不能保證。

此外,,您不能用syncExec的實例替換asyncExec的每個實例。 syncExec將等待有問題的runnable由UI線程發佈並執行,這可能會造成嚴重的爭用問題。假設這段代碼運行在非UI線程上:

synchronized(foo) 
{ 
    display.asynExec(new Runnable() { 
     public void run() 
     { 
      synchronized(foo) 
      { 
       System.out.println("Hello!"); 
      } 
     } 
    }); 
} 

這是一個簡單的例子 - 但它不會死鎖。 asyncExec調用將對此可運行和返回進行排隊,這將從​​塊中退出,以便UI線程上的可運行內容稍後可以獲取鎖定。但是,用syncExec替換這個肯定會造成死鎖。

一般來說,建議使用asyncExec,除非您認爲您需要執行保證syncExec

+0

我認爲你可以刪除從「進一步,不..」,這與我的問題無關的部分。 – zedoo

1

無論從UI線程還是其他線程調用,SWT的Display都將正確處理syncExecasyncExec

如果您真的想要避免調用這些API的微小開銷,並且希望在發佈的代碼上執行同步執行,那麼做出這樣的檢查是有意義的。