2011-11-02 54 views
1

實現某些util方法暫停測試(當前線程)執行直到應用程序變爲空閒爲止是否可行?
空閒意味着:
1.在一段時間內沒有添加到事件隊列的GUI事件
2.在同一段時間內沒有工作線程運行任何任務。
您能否提供實現/代碼片段來跟蹤以前的閒置狀況?暫停測試執行,直到應用程序變爲空閒

回答

1

您可以使用Toolkit.getDefaultToolkit().addAWTEventListener(listener, eventMask)訂閱AWT事件隊列,以便您可以檢測是否在某段時間內未添加事件。

我認爲您需要您的自定義代碼來監視工作線程,即在run()方法的開始和結束處。

問題是「暫停測試執行」。如果你的測試在理論上是在線程中運行的,你可以調用線程的方法suspend()。但它已被棄用,不應使用。爲了執行清晰的實現,您應該使您的自定義代碼在執行線程期間詢問狀態,並在檢測到必須暫停測試時調用wait()。當監控AWT事件隊列和工作線程的代碼決定可以恢復測試時,它應該調用適當的notify()

從設計的角度來看,可能更好的解決方案是Actors模型。有幾個提供這種功能的java框架。

+0

「掛起測試執行」沒有問題。我將從測試本身使用該util方法,因此我將使用LockSupport.park *暫停測試,就像ReentrantLock一樣。問題是「追蹤無知」。感謝有關GUI事件的想法。 –

2

您可以用您自己的實施替換EventQueue,如here所示。下面的變化增加了一個idle()方法,它依賴於1000毫秒的任意THRESHOLD

import java.awt.AWTEvent; 
import java.awt.EventQueue; 
import java.awt.Toolkit; 
import java.lang.reflect.InvocationTargetException; 
import javax.swing.JFrame; 
import javax.swing.JTree; 

/** 
* @see https://stackoverflow.com/questions/7976967 
* @see https://stackoverflow.com/questions/3158254 
*/ 
public class EventQueueTest { 

    public static void main(String[] args) throws 
      InterruptedException, InvocationTargetException { 
     EventQueue eventQueue = Toolkit.getDefaultToolkit().getSystemEventQueue(); 
     final MyEventQueue q = new MyEventQueue(); 
     eventQueue.push(q); 

     EventQueue.invokeAndWait(new Runnable() { 

      @Override 
      public void run() { 
       JFrame f = new JFrame("Test"); 
       f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
       f.add(new JTree()); 
       f.pack(); 
       f.setVisible(true); 
      } 
     }); 
     // Test idle() on initial thread 
     for (int i = 0; i < 10; i++) { 
      Thread.sleep(2 * MyEventQueue.THRESHOLD); 
      System.out.println("Idle: " + q.idle()); 
     } 
    } 

    private static class MyEventQueue extends EventQueue { 

     private static final int THRESHOLD = 1 * 1000; 
     private long last; 

     @Override 
     public void postEvent(AWTEvent e) { 
      super.postEvent(e); 
      last = System.currentTimeMillis(); 
     } 

     public boolean idle() { 
      return System.currentTimeMillis() - last > THRESHOLD; 
     } 
    } 
} 
+0

嗯奇怪,但作品,感謝您的想法+1 – mKorbel

+0

我_think_這是全面的;另請參閱[Q&A](http://stackoverflow.com/questions/7787998/how-to-generate-exceptions-from-repaintmanager)瞭解如何查找EDT違規。 – trashgod

+0

這個解決方案不是用來傳遞事件處理時間小於重新檢查時間間隔的事實。通過比較最後一次調度時間,您不能保證沒有等待執行的待處理事件。你可以檢查隊列是否爲空(有API),但這也不會工作。需要'正在進行'的標記檢查是否檢查空隊列。但是這也不起作用,因爲有'閃爍'事件隊列的提示(把hadware事件放到應用程序的事件隊列中)。 –