ScheduledThreadPoolExecutor并发任务

时间:2017-12-24 16:55:13

标签: java java.util.concurrent

我已经对这个主题进行了很多研究,但找不到任何有用的信息。我决定在这个平台上提出我的第一个问题。因此,我使用预定的执行程序在特定时间段内重复任务。一切都好。但是存在一个误解......我的代码执行任务但是如果任务花费的时间比调度时间长,那么它等待完成任务然后开始执行新任务。我希望它在计划时间到来时执行任务,并且不要等待上一个任务完成。我怎样才能做到这一点?我在Swing项目中使用了SwingWorker,但这个项目不是一个摇摆项目。谢谢你的阅读。

主要方法

        LogFactory.log(LogFactory.INFO_LEVEL, Config.MODULE_NAME + " - Available processors for Thread Pool: " + AVAILABLE_PROCESSORS);
    ScheduledExecutorService executor = Executors.newScheduledThreadPool(AVAILABLE_PROCESSORS);
    LogFactory.log(LogFactory.INFO_LEVEL, Config.MODULE_NAME + " - [ScheduledExecutorService] instance created.");
    MainWorker task = new MainWorker();
    LogFactory.log(LogFactory.INFO_LEVEL, Config.MODULE_NAME + " - [Main worker] created...");
    executor.scheduleWithFixedDelay(task, 0, Config.CHECK_INTERVAL, TimeUnit.SECONDS);

主要工作人员

public class MainWorker implements Runnable {

private final NIFIncomingController controller = new NIFIncomingController();

@Override
public void run() {
    LogFactory.log(LogFactory.INFO_LEVEL, Config.MODULE_NAME + " - [Task] executed - [" + Thread.currentThread().getName() + "]");
    controller.run();
}

}

2 个答案:

答案 0 :(得分:0)

您可以尝试组合多个执行程序以实现所需的行为。请在下面找到示例代码:

import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;


public class CombinedThreadPoolsExample {

    private static final DateFormat DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
    private static final int INITIAL_DELAY = 0;
    private static final int FIXED_DELAY_IN_MILLISECONDS = 1000;
    private static final int TASK_EXECUTION_IN_MILLISECONDS = FIXED_DELAY_IN_MILLISECONDS * 2;

    public static void main(String[] args) {
        int availableProcessors = Runtime.getRuntime().availableProcessors();
        System.out.println("Available processors: [" + availableProcessors + "].");
        ExecutorService fixedThreadPool = Executors.newFixedThreadPool(availableProcessors);

        Runnable runnableThatTakesMoreTimeThanSpecifiedDelay = new Runnable() {
            @Override
            public void run() {
                System.out.println("Thread name: [" + Thread.currentThread().getName() + "], time: [" + DATE_FORMAT.format(new Date()) + "].");
                try {
                    Thread.sleep(TASK_EXECUTION_IN_MILLISECONDS);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        };

        ScheduledExecutorService singleThreadScheduledExecutor = Executors.newSingleThreadScheduledExecutor();
        singleThreadScheduledExecutor.scheduleWithFixedDelay(new Runnable() {
            @Override
            public void run() {
                fixedThreadPool.execute(runnableThatTakesMoreTimeThanSpecifiedDelay);
            }
        }, INITIAL_DELAY, FIXED_DELAY_IN_MILLISECONDS, TimeUnit.MILLISECONDS);
    }
}

输出的第一行是我的机器:

Available processors: [8].
Thread name: [pool-1-thread-1], time: [2017-12-25 11:22:00.103].
Thread name: [pool-1-thread-2], time: [2017-12-25 11:22:01.104].
Thread name: [pool-1-thread-3], time: [2017-12-25 11:22:02.105].
Thread name: [pool-1-thread-4], time: [2017-12-25 11:22:03.105].
Thread name: [pool-1-thread-5], time: [2017-12-25 11:22:04.106].
Thread name: [pool-1-thread-6], time: [2017-12-25 11:22:05.107].
Thread name: [pool-1-thread-7], time: [2017-12-25 11:22:06.107].
Thread name: [pool-1-thread-8], time: [2017-12-25 11:22:07.107].
Thread name: [pool-1-thread-1], time: [2017-12-25 11:22:08.108].
Thread name: [pool-1-thread-2], time: [2017-12-25 11:22:09.108].
Thread name: [pool-1-thread-3], time: [2017-12-25 11:22:10.108].
Thread name: [pool-1-thread-4], time: [2017-12-25 11:22:11.109].

但是,当任务执行需要很长时间时,请注意依赖此类解决方案,与池大小进行比较。我们假设我们增加了执行任务所需的时间:

private static final int TASK_EXECUTION_IN_MILLISECONDS = FIXED_DELAY_IN_MILLISECONDS * 10;

这不会导致执行期间出现任何异常,但无法在执行之间强制执行指定的延迟。在上述延迟改变之后,可以在执行输出中观察到:

Available processors: [8].
Thread name: [pool-1-thread-1], time: [2017-12-25 11:31:23.258].
Thread name: [pool-1-thread-2], time: [2017-12-25 11:31:24.260].
Thread name: [pool-1-thread-3], time: [2017-12-25 11:31:25.261].
Thread name: [pool-1-thread-4], time: [2017-12-25 11:31:26.262].
Thread name: [pool-1-thread-5], time: [2017-12-25 11:31:27.262].
Thread name: [pool-1-thread-6], time: [2017-12-25 11:31:28.263].
Thread name: [pool-1-thread-7], time: [2017-12-25 11:31:29.264].
Thread name: [pool-1-thread-8], time: [2017-12-25 11:31:30.264].
Thread name: [pool-1-thread-1], time: [2017-12-25 11:31:33.260].
Thread name: [pool-1-thread-2], time: [2017-12-25 11:31:34.261].
Thread name: [pool-1-thread-3], time: [2017-12-25 11:31:35.262].

答案 1 :(得分:0)

这可以通过使用单个执行程序服务来实现。说你的日程安排时间是Y

  • 确定最坏情况下任务可以采取的时间。说X
  • 如果它不受控制,则在任务实现中控制它以识别超时。
  • 如果X>是,然后创建另一个任务对象并将计划时间加倍
  • 所以代码可能看起来像
board()
  • 如果X> n(Y)然后创建n + 1个任务,预定时间为(n + 1)Y,初始延迟分别为0,2Y,3Y ......(n-1)Y。