暂停测试执行,直到应用程序变为空闲

问题描述:

实现某些util方法暂停测试(当前线程)执行直到应用程序变为空闲为止是否可行?
空闲意味着:
1.在一段时间内没有添加到事件队列的GUI事件
2.在同一段时间内没有工作线程运行任何任务。
您能否提供实现/代码片段来跟踪以前的闲置状况?暂停测试执行,直到应用程序变为空闲

您可以使用Toolkit.getDefaultToolkit().addAWTEventListener(listener, eventMask)订阅AWT事件队列,以便您可以检测是否在某段时间内未添加事件。

我认为您需要您的自定义代码来监视工作线程,即在run()方法的开始和结束处。

问题是“暂停测试执行”。如果你的测试在理论上是在线程中运行的,你可以调用线程的方法suspend()。但它已被弃用,不应使用。为了执行清晰的实现,您应该使您的自定义代码在执行线程期间询问状态,并在检测到必须暂停测试时调用wait()。当监控AWT事件队列和工作线程的代码决定可以恢复测试时,它应该调用适当的notify()

从设计的角度来看,可能更好的解决方案是Actors模型。有几个提供这种功能的java框架。

+0

“挂起测试执行”没有问题。我将从测试本身使用该util方法,因此我将使用LockSupport.park *暂停测试,就像ReentrantLock一样。问题是“追踪无知”。感谢有关GUI事件的想法。 –

您可以用您自己的实施替换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://*.com/questions/7976967 
* @see https://*.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://*.com/questions/7787998/how-to-generate-exceptions-from-repaintmanager)了解如何查找EDT违规。 – trashgod

+0

这个解决方案不是用来传递事件处理时间小于重新检查时间间隔的事实。通过比较最后一次调度时间,您不能保证没有等待执行的待处理事件。你可以检查队列是否为空(有API),但这也不会工作。需要'正在进行'的标记检查是否检查空队列。但是这也不起作用,因为有'闪烁'事件队列的提示(把hadware事件放到应用程序的事件队列中)。 –