在特定时间运行java线程仅在特定持续时间内运行一次然后停止

时间:2018-03-08 22:07:48

标签: java multithreading

我正在尝试创建一个将在特定时间执行的线程,持续一段特定的时间并且只运行一次,然后停止直到再次调用它。

问题在于,无论何时执行线程,它都不会在一段时间内执行,它只会打印一个" Hi"然后立即停止。 如果我删除该标志,该线程将永远运行。

  public void startExecutionAt(int targetHour, int targetMin, int duration)
    {
       log.info("Create thread!");
       Runnable taskWrapper= new Runnable(){
            @Override
            public void run() 
            {
                if(runsFirst==true){
                    log.info("Thread inside!");
                    WateringScheduler.execute();
                    startExecutionAt(targetHour, targetMin, duration);
                }
                else{
                    log.info("Thread stoped!");
                    stop();
                    //close the led
                }
                runsFirst=false;
            }

        };

        long delay = computeNextDelay(targetHour, targetMin);
        System.out.println("Delay is : " + delay + " Duration is: " +duration);
        executorService.scheduleAtFixedRate(taskWrapper, delay,duration, TimeUnit.SECONDS);
    }


    private static long computeNextDelay(int targetHour, int targetMin) {
         LocalDateTime localNow = LocalDateTime.now();
         ZoneId currentZone = ZoneId.systemDefault();
         ZonedDateTime zonedNow = ZonedDateTime.of(localNow, currentZone);          
         ZonedDateTime zonedNextTarget = zonedNow.withHour(targetHour).withMinute(targetMin);

        if (zonedNow.compareTo(zonedNextTarget) > 0) {
            zonedNextTarget = zonedNextTarget.plusDays(1);
        }

        Duration duration = Duration.between(zonedNow, zonedNextTarget);
        return duration.getSeconds();
    }


    public void stop()
    {
        executorService.shutdown();
        try {
            executorService.awaitTermination(1, TimeUnit.DAYS);
        } catch (InterruptedException ex) {
          log.error("Error");;
        }
    }
    public static void execute(){
        System.out.println("Hi");
        //open the led;
    }

1 个答案:

答案 0 :(得分:1)

我使用ScheduledExecutorService感到困惑。

根据javadocs,“ScheduledFuture计划创建并执行一次性动作,在给定的延迟后启用。”

下面的代码执行一次线程并在(延迟+持续时间)+1后停止。

 public void startExecutionAt(int targetHour, int targetMin, int duration)
    {
       log.info("Create thread!");
       long delay = computeNextDelay(targetHour, targetMin);
       final Runnable executeR = new Runnable() {
                    public void run() {
                        try {
                            execute();
                        }catch(Exception ex) {
                              log.error("Error in thread" + ex.getMessage());
                        }
                    }
       };

       final ScheduledFuture<?> executeHandler = executorService.scheduleAtFixedRate(executeR,delay, duration, TimeUnit.SECONDS);

       executorService.schedule(
          new Runnable() {
           public void run() { 
               log.info("Thread is stopping");
               executeHandler.cancel(true); 
           }
         }, delay+duration+1, TimeUnit.SECONDS);

       System.out.println("Delay is : " + delay + " Duration is: " +duration);
        log.info("Thread out");
    }


    private static long computeNextDelay(int targetHour, int targetMin) {
         LocalDateTime localNow = LocalDateTime.now();
         ZoneId currentZone = ZoneId.systemDefault();
         ZonedDateTime zonedNow = ZonedDateTime.of(localNow, currentZone);          
         ZonedDateTime zonedNextTarget = zonedNow.withHour(targetHour).withMinute(targetMin);

        if (zonedNow.compareTo(zonedNextTarget) > 0) {
            zonedNextTarget = zonedNextTarget.plusDays(1);
        }

        Duration duration = Duration.between(zonedNow, zonedNextTarget);
        return duration.getSeconds();
    }


    public void stop()
    {
        executorService.shutdown();
        try {
            executorService.awaitTermination(1, TimeUnit.DAYS);
        } catch (InterruptedException ex) {
          log.error("Error");;
        }
    }