2016-05-16 108 views
0

我有一个自定义日志,它获取由后台线程或由用户鼠标单击事件触发的主线程打印的数据。这两个线程可能会同时在日志中打印。代码是这样的从同步方法调用的Eclipse SWT:Display.syncExec()

public void appendLine(String s, int type) { 
    synchronized (this) { 
     int index = setInputLine(s); 
     if (type == BG) { 
      updateConsole(); 
     } 
     else if (type == UI) { 
      printConsole(); 
     } 
    } 
} 

方法setInputLines(),updateConsole()和printConsole()作为同步没有被定义。方法updateConsole()从后台线程打印像这样

public void updateConsole() { 
    Display.syncExec(new Runnable() { 
     // update widgets UI here 
    }); 
} 

但是,上述代码逻辑在测试中失败。方法appendLine()从测试后台线程中调用,并且当主线程试图通过同时调用appendLine()来获取锁时,它总是在Display.syncExec()处挂起。任何人都知道为什么?谢谢

+0

你是说'syncExec'中的代码调用'appendLine'吗? –

+0

appendLine()正在调用updateConsole()。 updateConsole()调用Display.syncExec()。问题是,如果后台线程调用appendLine(),则主线程不能同时调用appendLine()。否则程序挂起。 – CMZS

+1

'syncExec'是一个阻塞呼叫,如果其他人已经在呼叫它。 – nitind

回答

0

Display.syncExec将阻塞调用它的线程,直到它可以运行 - 直到下一次UI线程在主UI循环中调用Display.readAndDispatch时才会执行此操作。

如果主UI线程在运行readAndDispatch之前调用appendLine,UI线程将被阻塞,等待​​块,然后发生死锁。

因此,从这样的同步块内调用syncExec是不安全的。

您可能可以使用asyncExec而不是syncExec,因为这不会阻塞该线程。

+0

非常感谢 – CMZS