How to run two methods as thread one after another using ExecuterService

2.4k views Asked by At

I am trying to execute two method where two methods will execute one by one after some interval, and I am using ExecuterService. I have implemented some portion of the code but the full functionality I could not achieve till now, here I am posting my code

public class ExampleExecuterService {

private static final int MYTHREADS = 3000;
public static void main(String[] args) throws Exception {

    ExecutorService executor = Executors.newFixedThreadPool(MYTHREADS);

    Object methodList[]={

            aMethod(),bMethod()
    };


    for(int i=0;i<methodList.length;i++){
        Object myList = methodList[i];
        Runnable worker = new MyRunnable(myList);
        executor.execute(worker);
    }
    executor.shutdown();
    // Wait until all threads are finish
            while (!executor.isTerminated()) {

            }
  System.out.println("\nFinished all threads");

}

public static class MyRunnable implements Runnable {

    private Object myList=null;

    MyRunnable(Object myList) {
        this.myList = myList;
    }
    @Override
    public void run() {


        try{

            myList.wait(2000);
        }catch(Exception e){
            e.printStackTrace();
        }
    }


}

private static Object bMethod() {
    System.out.println("This is inside method a ");
    return null;
}
private static Object aMethod() {

    System.out.println("This is inside method b ");
    return null;
}

}

I want aMethod() and bMethod() that should run 20 seconds after and in the end the executer will stop. How to do that with my code. Somebody please help me.

2

There are 2 answers

3
Eric Leibenguth On BEST ANSWER
Object methodList[]={
   aMethod(),bMethod()
};

This is not a list of your methods. This is a list of what your methods return (=null).

In Java, methods are not objects. If you want to store methods in a list or array, you have to wrap them inside objects. The usual way of doing this is by using the Runnable interface or something of the kind.

In your case, it could look like this:

Runnable[] methods = new Runnable[]{
   new Runnable(){  // Object wrapper for method a
       @Override
       public void run(){  // method a
          System.out.println("This is inside method a");
       }
   },
   new Runnable(){  // Object wrapper for waiting
       @Override
       public void run(){   // method to wait for 20s
          try{ Thread.sleep(20000); }catch(Exception e){}
       }
   },
   new Runnable(){  // Object wrapper for method b
       @Override
       public void run(){  // method b
          System.out.println("This is inside method b");
       }
   }
};

After that you can submit this array of "methods" to your executor service:

ExecutorService service = Executors.newSingleThreadExecutor();
for(Runnable r : methods)
   service.submit(r);
service.shutdown();

However, keep in mind that ExecutorService is primarily meant to execute tasks concurrently (= in parallel), while you want to execute them sequentially.

In you know that you'll always need a sequential, single-thread behaviour, you should drop ExecutorService and simply:

for(Runnable r : methods) 
   r.run();

EDIT: Full main method

public static void main(String[] args) throws Exception {

    Runnable[] methods = new Runnable[]{
       new Runnable(){  // Object wrapper for method a
           @Override
           public void run(){  // method a
              System.out.println("This is inside method a");
           }
       },
       new Runnable(){  // Object wrapper for waiting
           @Override
           public void run(){   // method to wait for 20s
              try{ Thread.sleep(20000); }catch(Exception e){}
           }
       },
       new Runnable(){  // Object wrapper for method b
           @Override
           public void run(){  // method b
              System.out.println("This is inside method b");
           }
       }
    };

    ExecutorService service = Executors.newSingleThreadExecutor();
    for(Runnable r : methods)
       service.submit(r);
    service.shutdown();

    // Wait until all threads are finish
    while (!service.isTerminated()) {}
    System.out.println("\nFinished all threads");
}
0
Uri Shalit On

I didn't find a better solution for the waiting 20 seconds in between, but how about this:

    ExecutorService service = Executors.newSingleThreadExecutor();
    service.submit(task1);
    service.submit(() -> {
        Thread.sleep(20000);
        return null;
    });
    service.submit(task2);