使用ExecutorService并行处理任务

时间:2016-12-01 20:53:40

标签: java multithreading parallel-processing

我正在编写一个需要并行监视多台机器的java程序。此数字不固定,可在程序执行期间随时变化(增加/减少)。

我在考虑做这样的事情:

public static void main (String args[]) {

    ExecutorService EXEC1 = Executors.newScheduledThreadPool(1);

    EXEC1.scheduleWithFixedDelay(new Runnable() {

        ExecutorService EXEC2 = Executors.new...
        Map<Integer, Future<Void>> monitoringTasks = new HashMap<Integer, Future<Void>>();

        @Override
        public void run() {

            List<Machine> monitorizedMachines = MachineDao.getMonitorizedMachines();

            for (Machine machine: monitorizedMachines) {

                Future<Void> monitoringTask = monitoringTasks.get(machine.getId());

                if(monitoringTask == null || monitoringTask.isDone()) {

                    monitoringTask = EXEC2.submit(new Runnable() {
                        @Override
                        public void run() throws Exception {

                            // monitor machine....

                        }
                    });

                    monitoringTasks.put(machine.getId(), monitoringTask);
                }

            }
        }

    }, 1, 1, TimeUnit.SECONDS);

}

但是我在这种情况下选择最合适的Executor(EXEC2)时遇到了麻烦:FixedThreadPool,CachedThreadPool,Custom Implementation,...

需要说每个监控任务大约需要2/3秒。

有人可以给我任何建议吗?

2 个答案:

答案 0 :(得分:0)

大多数情况下,当您开发基于生产的大型应用程序时,您需要使用ExecutorService EXEC2 = Executors.newFixedThreadPool(THREAD_COUNT);,并且需要在执行性能测试后正确配置THREAD_COUNT w 与预期的请求/数量相关

您可以查看here,了解newCachedThreadPool()对于请求量较大的应用程序不理想的原因的详细信息。

答案 1 :(得分:0)

这是一个简单的例子。 在您的类中首先添加示例公共变量boolean ISWORKING。在run()代码中,在变量之间添加代码,如下一个示例:

public static class Machine implements Runnable {

        public boolean ISWORKING = true;

        @Override
        public void run() {
            this.ISWORKING = true;
            //YOUR CODE HERE..................
            this.ISWORKING = false;
        }

    }

第二个示例代码:

    Timer timer = null;
    TimerTask task = null;
    boolean isLocked = false;

    public void main() {

        task = new TimerTask() {

            @Override
            public void run() {

                if (isLocked) {
                    return;
                }

                isLocked = true;

                List<Machine> monitorizedMachines = MachineDao.getMonitorizedMachines();

                //Count the pending job.
                int poolsize = 0;
                for (Machine machine : monitorizedMachines) {

                    if (!machine.ISWORKING) {
                        poolsize++;
                    }

                }

                if (poolsize == 0) {
                    isLocked = false;
                    return;
                }

                //Prevent a lot of poolsize.
                poolsize = Math.min(100, poolsize);

                ThreadPoolExecutor pool = (ThreadPoolExecutor) Executors.newFixedThreadPool(poolsize);

                for (Machine machine : monitorizedMachines) {

                    if (!machine.ISWORKING) {
                        pool.execute(machine);
                    }

                }
                pool.shutdown();


                isLocked = false;

            }

        };

        timer = new Timer();
        timer.schedule(task, 1000, 2000);

    }