Java 如果上一个任务未完成,如何不启动ScheduledExecutorService任务

Java 如果上一个任务未完成,如何不启动ScheduledExecutorService任务,java,multithreading,scheduledexecutorservice,Java,Multithreading,Scheduledexecutorservice,我的问题是我们必须给它一个固定的计划时间,让它开始任务。假设我给10秒,我的任务平均完成时间为10-15秒。因此,等待一段时间后,quque中的线程会导致巨大的内存消耗。如果我对上述方法使用syncronized,则会出现问题。如果我不使用syncronized,那么我是在浪费资源(cpu),因为如果任务没有完成,我就不需要运行任务。所以我想到了任务递归调用的解决方案,但我相信递归线程会增加更多内存问题。。。我该怎么办?很快,我只想在任务完成后调用它。不是固定时间 public void myS

我的问题是我们必须给它一个固定的计划时间,让它开始任务。假设我给10秒,我的任务平均完成时间为10-15秒。因此,等待一段时间后,quque中的线程会导致巨大的内存消耗。如果我对上述方法使用
syncronized
,则会出现问题。如果我不使用
syncronized
,那么我是在浪费资源(cpu),因为如果任务没有完成,我就不需要运行任务。所以我想到了任务递归调用的解决方案,但我相信递归线程会增加更多内存问题。。。我该怎么办?很快,我只想在任务完成后调用它。不是固定时间

public void myScheduledTask{
    doJob(); ( use countdown latch to control waiting if necessary)
    TimeUnit.SECONDS.sleep(x);
    new Thread( new Runnable( { mySchedulTask();   } ));
    or
    executor.execute( a thread that call myScheduledTask() method);
}

听起来像是你想要实现的选择:

ScheduledExecutorService executor = Executors.newScheduledThreadPool(count);
ScheduledFuture<?> future = executor.scheduleWithFixedDelay(
                                   task, 
                                   delay, 
                                   delay, 
                                   TimeUnit.MILLISECONDS
                                  );

现在,您将创建从未使用过的未来,因此控制任务的执行将变得更加困难。

听起来像是您正在尝试完成的选项:

ScheduledExecutorService executor = Executors.newScheduledThreadPool(count);
ScheduledFuture<?> future = executor.scheduleWithFixedDelay(
                                   task, 
                                   delay, 
                                   delay, 
                                   TimeUnit.MILLISECONDS
                                  );

现在,您将创建从未使用过的未来,因此更难控制任务的执行。

在任务类-Lock中创建静态成员。 在doJob中,如果已获得锁,请避免执行作业:

 if (lock.tryLock()) {
      try {
          // do the job
      } finally {
          lock.unlock();
      }
  } else {
      // log the fact you skipped the job
      return;
  }

在任务类中创建静态成员-Lock。 在doJob中,如果已获得锁,请避免执行作业:

 if (lock.tryLock()) {
      try {
          // do the job
      } finally {
          lock.unlock();
      }
  } else {
      // log the fact you skipped the job
      return;
  }


如果一次只能执行一个任务,那么就使用一个有一个线程的调度线程池来执行这些任务。我不太明白你的意思。你能详细说明一下吗?谢天谢地,不要把事情搞得太复杂了,这是一个简单的例子,如果你加的比减的多,那么你肯定会积累线程阻塞。在这种情况下不使用Synchronized并不是一种解决方法,您只会给自己带来麻烦。在我看来,您需要使用ThreadPoolExecutor。你为什么反对使用这样的野兽?@Mat我只是想在任务完成后能够调用它。非固定时间。@MertSerimerAlumni buyurun abi,这有帮助吗:如果任务需要一次限制在一个线程上,那么使用一个计划线程池和一个线程来完成这些任务。我不太明白你的意思。你能详细说明一下吗?谢天谢地,不要把事情搞得太复杂了,这是一个简单的例子,如果你加的比减的多,那么你肯定会积累线程阻塞。在这种情况下不使用Synchronized并不是一种解决方法,您只会给自己带来麻烦。在我看来,您需要使用ThreadPoolExecutor。你为什么反对使用这样的野兽?@Mat我只是想在任务完成后能够调用它。非固定时间。@MertSerimerAlumni buyurun abi,这有帮助吗:您认为这与使用同步保护资源不同吗?是的,如果当前尝试仍然有效,则跳过(而不是延迟)下一次尝试。最明显的效果是:永远不会有很多锁定的线程在等待资源。这并不适用于所有场景,因为没有保证实际执行jobDone“meat”的数量。但是,对于外部启动的维护任务(例如,由Quartz启动的维护任务),这是可以的。您认为这与使用synchronized保护资源不同吗?是的,如果当前任务仍在工作,则跳过(而不是延迟)下一次尝试。最明显的效果是:永远不会有很多锁定的线程在等待资源。这并不适用于所有场景,因为没有保证实际执行jobDone“meat”的数量。但是,对于外部启动的维护任务(例如,由Quartz启动的维护任务)是可以的。executor是否总是等待当前线程完成才能启动新线程?为什么您关心它是否启动新线程?它将根据资源和提交方式执行您提交的任务。这是浪费,因为在当前信息出现之前我不需要新信息。另外,如果它在完成之前启动,那么子线程的创建量将超过它应该创建的数量(cpu核心数)等等。首先,它处理线程。完成后,不要谈论创建新线程。您可以在创建服务时设置线程数。这就是变量
count
的作用。如果您计划任务以固定的延迟发生,则该任务将永远不会同时运行。run方法将被调用,在它完成任务后,执行器将等待
延迟
毫秒,然后再次启动任务。谢谢,它确保任务在启动新线程之前完成。执行器是否总是等待当前线程完成以启动新线程?您为什么关心它是否启动新线程?它将根据资源和提交方式执行您提交的任务。这是浪费,因为在当前信息出现之前我不需要新信息。另外,如果它在完成之前启动,那么子线程的创建量将超过它应该创建的数量(cpu核心数)等等。首先,它处理线程。完成后,不要谈论创建新线程。您可以在创建服务时设置线程数。这就是变量
count
的作用。如果您计划任务以固定的延迟发生,则该任务将永远不会同时运行。run方法将被调用,在它完成任务后,执行器将等待
延迟
毫秒,然后再次启动任务。谢谢,它确保任务在启动新任务之前完成。