【发布时间】:2012-05-22 09:23:16
【问题描述】:
我需要启动一个任务。现在很多线程都可以启动这个任务,这个任务通常需要 4-5 秒才能完成。如果该任务已由其他线程启动,我想阻止该任务的启动。 为了实现此要求,我正在考虑在某个线程启动任务时在不同的线程中启动计时器或秒表。现在,当定时器在配置的时间间隔后超时时,另一个线程可以启动一个任务。 那么,在不同的线程中启动计时器或秒表以查看是否已达到特定时间是一个好的解决方案吗?有什么好的替代方案吗?
【问题讨论】:
标签: java
我需要启动一个任务。现在很多线程都可以启动这个任务,这个任务通常需要 4-5 秒才能完成。如果该任务已由其他线程启动,我想阻止该任务的启动。 为了实现此要求,我正在考虑在某个线程启动任务时在不同的线程中启动计时器或秒表。现在,当定时器在配置的时间间隔后超时时,另一个线程可以启动一个任务。 那么,在不同的线程中启动计时器或秒表以查看是否已达到特定时间是一个好的解决方案吗?有什么好的替代方案吗?
【问题讨论】:
标签: java
如果我理解正确,这是个坏主意。基本上你假设你的工作永远不会运行超过 5 秒,所以如果手表告诉你某个工作是在不到 5 秒前开始的,你就不会开始另一个工作。这是非常不可靠的。
而是创建某种标志,在作业开始时设置并在结束时取消设置。 AtomicBoolean 非常适合:
private AtomicBoolean flag = new AtomicBoolean();
//...
if(!flag.getAndSet(true)) {
try {
//do your work
} finally {
flag.set(false);
}
} else {
//Already running
}
如果您希望另一个作业等待前一个作业而不是简单地被丢弃,只需将您的任务用synchronized 包围或使用一些不同的锁定机制。
注意:如果您的作业是分布式的,您将需要分布式锁定机制,例如数据库或hazelcast。
【讨论】:
如果您尝试在 java 中执行此操作,那么您可以考虑在 JAVA 的面向对象方法中使用同步块。
因此,您要确保一次由一个线程完成的任何任务然后在该类中创建一个类和一个同步方法,还要确保所有线程共享该类的相同对象并调用此方法他们想要在其中执行任务。
举例
Class SyncTask{
synchronized void task1(){
//Perform your task here
}
}
在应用程序的生命周期内创建一次此类的对象,然后在所有线程中使用相同的对象,并让它们调用您想要执行任务的方法。
在多个线程同时调用该方法的情况下。 JVM 会处理这个序列,如果一个线程已经在执行任务,其他调用它的线程将等待第一个线程完成。
通过这种方式,您将确保在任何给定时间只有在线程上执行任务。
我希望这会有所帮助。
【讨论】: