1

I am writing a java program that needs to monitor a number of machines in parallel. This number is not fixed, it can vary (increase/decrease) at any time during the program execution.

I was thinking of doing something like this:

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);

}

But I having trouble picking the most suitable Executor (EXEC2) for this case: FixedThreadPool, CachedThreadPool, Custom Implementation, ...

It needs to say that each monitoring task is about 2/3 seconds long.

Can anyone give me any advice?

Ender_iii
  • 21
  • 3

2 Answers2

0

Most of the times, when you are developing large production based applications, you need to go with ExecutorService EXEC2 = Executors.newFixedThreadPool(THREAD_COUNT); and you need to rightly configure the THREAD_COUNT after conducting performance tests with the expected number of requests/volumes.

You can look here for more details on why newCachedThreadPool() is NOT ideal for applications with high volumes of requests.

Community
  • 1
  • 1
Vasu
  • 21,832
  • 11
  • 51
  • 67
0

This is a simple example how to. First in your class Machine add example a public variable boolean ISWORKING. In the run() code add your code between variable like next example:

public static class Machine implements Runnable {

        public boolean ISWORKING = true;

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

    }

Second example code:

    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);

    }
toto
  • 1,180
  • 2
  • 13
  • 30