0

I am attempting to executing a email job for every minute. Job has 5 services. Each 5 services should run in parallel.

Using ExecutorService :

ExecutorService service = null;
if (serviceMap != null && serviceMap.size() > 0) {

    for (;;) {
        service = Executors.newFixedThreadPool(serviceMap.size());  // Here Service Map size will be 5
        for (Map.Entry entry : serviceMap.entrySet()) {
            service.submit(new EmailService(conn, mailParam));
        }
        service.shutdown();
        service.awaitTermination(1, TimeUnit.MINUTES);
    }
}

Using ScheduledExecutorService :

ScheduledExecutorService scheduledExecutorService = null;
if (serviceMap != null && serviceMap.size() > 0) {
    scheduledExecutorService = Executors.newFixedThreadPool(serviceMap.size());  // Here Service Map size will be 5
    for (Map.Entry entry : serviceMap.entrySet()) {

        ScheduledFuture scheduledFuture =
                scheduledExecutorService.schedule(new EmailService(conn, mailParam),
                60,
                TimeUnit.SECONDS);
        System.out.println("result = " + scheduledFuture.get());
    }

    scheduledExecutorService.shutdown();
}

If I use ExecutorService, for every minute I shutdown the service and execute the service again. Is it all right?

If I use ScheduledExecutorService, I couldn't be able to write code to execute service in parallel and couldn't be able to run the job for every minute.

Above is my code snippet. Please help me to resolve it.

lapaczo
  • 746
  • 7
  • 10
deadend
  • 1,286
  • 6
  • 31
  • 52
  • Possible duplicate of [How to implement an ExecutorService to execute tasks on a rotation-basis?](http://stackoverflow.com/questions/10346187/how-to-implement-an-executorservice-to-execute-tasks-on-a-rotation-basis) – Adonis Feb 27 '17 at 10:36
  • They are not using ScheduledExecutorService to run periodically. – deadend Feb 27 '17 at 10:38

2 Answers2

2

First of all, you should call newScheduledThreadPool() that creates ScheduledExecutorService, which is the correct scheduling executor service.
Then you should use [scheduleAtFixedRate][1] method to schedule a task every minute with initial delay 60 seconds.

ScheduledExecutorService scheduledExecutorService = null;
if (serviceMap != null && serviceMap.size() > 0) {
    scheduledExecutorService = Executors.newScheduledThreadPool(serviceMap.size());  // Here Service Map size will be 5
    for (Map.Entry entry : serviceMap.entrySet()) {
        scheduledExecutorService.scheduleAtFixedRate(new EmailService(conn, mailParam),
                60,
                60,
                TimeUnit.SECONDS);
    }
}
lapaczo
  • 746
  • 7
  • 10
  • scheduleAtFixedRate ask Runnable as parameter, but i want Callable as parameter. – deadend Feb 28 '17 at 04:05
  • You can use [`RunnableFuture`](https://docs.oracle.com/javase/7/docs/api/java/util/concurrent/RunnableFuture.html) instead. But you end up with 5 `ScheduledFuture`. Better would be to use call backs. – lapaczo Feb 28 '17 at 08:12
  • Ok OLA Thanks. Since it is multi threaded, is it needed different connection for every thread? – deadend Feb 28 '17 at 08:39
  • EmailService will trigger 5 set of services. Inside EmailService class i wrote ExecutorService with [Executors.newFixedThreadPool(5)] – deadend Feb 28 '17 at 08:48
0

Good question !!

You have to separate it as two classes.

One is to start scheduler. Another one for execute the service which implements Callable or Runnable interface.

scheduledExecutorService.schedule() is different from service.submit().

schedule() is used to schedule a process whereas submit is used for submitting the services.

Start Scheduler Class :

public static void main(String[] args) {
        Class2 runnable = new Class2() {
          @Override
          public void run() {
            // call method that has ExecuteService Impl
          }
        };
        ScheduledExecutorService service = Executors.newSingleThreadScheduledExecutor();
        service.scheduleAtFixedRate(runnable, 0, 60, TimeUnit.SECONDS);
  }