我在多线程中不是很好,这可能是一个基本问题。但我一直无法找到答案。增加睡眠/等待时间直到需要
场景: 比方说,我有一个事件监听器被某些东西触发。每次事件被解雇,我都想开始一个新的线程,需要大约3秒钟的时间来执行。
问题: 问题是该事件可以在一秒钟内多次触发,而且我不想一次启动多个线程。
要求: 我该如何安排一个线程让事件发生后1000毫秒。如果事件继续发射,我想继续延迟线程的预定时间。这样,我的线程在上次事件被触发1000毫秒后执行。
我在多线程中不是很好,这可能是一个基本问题。但我一直无法找到答案。增加睡眠/等待时间直到需要
场景: 比方说,我有一个事件监听器被某些东西触发。每次事件被解雇,我都想开始一个新的线程,需要大约3秒钟的时间来执行。
问题: 问题是该事件可以在一秒钟内多次触发,而且我不想一次启动多个线程。
要求: 我该如何安排一个线程让事件发生后1000毫秒。如果事件继续发射,我想继续延迟线程的预定时间。这样,我的线程在上次事件被触发1000毫秒后执行。
我会使用一个ScheduledExecutorService
- 安排任务在一秒内发生,如果有任务已经安排取消它并安排一个新的发生在一秒
这样,您的任务将在事件最后一次触发后执行一秒钟。
private class Task implements Runnable {
@Override
public void run() {
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}
}
private final ScheduledExecutorService executorService = Executors.newSingleThreadScheduledExecutor();
private Future<?> scheduledTaskHandle;
private class Listener implements ActionListener {
@Override
public void actionPerformed(ActionEvent e) {
if (scheduledTaskHandle != null && !scheduledTaskHandle.isDone()) {
scheduledTaskHandle.cancel(false);
}
scheduledTaskHandle = executorService.schedule(new Task(), 1, TimeUnit.SECONDS);
}
}
的Task
是Runnable
,做您的长时间运行的操作。 Listener
是您的听众类。
在Listener.actionPerformed
方法中,我们首先通过使用Future
来检查是否已经安排了一个任务,如果我们取消它。我们不需要担心这里的种族危害,如果任务在isDone
的电话和cancel
的电话之间完成,则不会发生任何事情。
如果任务是在点运行时,Listener
火灾则该任务将完成,因为cancel
方法被调用false
。另一个任务将计划在侦听器触发后运行一秒,或者当前运行的任务完成后(因为我们只使用一个线程,只有一个任务可以运行)。
Listener
然后将安排任务的新执行在一秒钟内完成。
事件监听器在启动时创建并启动一个新的专用线程。线程包含要执行的任务列表,并按顺序逐个执行它们。每当偶数侦听器收到一个新事件时,它就会创建一个新任务,并将其添加到专用线程中的任务列表中。
编辑:尤金建议使用线程池,这可能会对您的情况有好处,如果您需要花费大量时间处理每项任务的大量工作。看看Java API中的线程池,像这样:http://docs.oracle.com/javase/tutorial/essential/concurrency/pools.html
你为什么在一个单独的线程中执行动作?为什么不在actionPerformed方法本身? –
@VishalK如果每次发生事件,OP可能不想阻止EDT。 –