amit
amit

Reputation: 153

Want ThreadPoolExecutor to execute tasks instantly

I have a ThreadPoolExecutor with one thread that will be used for batch processing, So before assigning a new task to the executor i have to wait for the earlier task to complete, i was doing this by depending upon the value for active jobs, but seeing in detail i found that, the executor doesn't executes the task instantly.

The problem this is causing to me is that i am ready to give the next batch but the first task has not yet started thus the value of active jobs is 0.

How can i get to run the task instantly. I am also OK with any other executor or way that this can be done.

Upvotes: 1

Views: 2117

Answers (3)

Basil Bourque
Basil Bourque

Reputation: 338775

Single thread pool executor service

Apparently you want to run multiple tasks immediately but in the order submitted.

Quite easy: Use an executor service backed by a single thread. The executor buffers up the tasks while waiting on earlier ones to complete. With on a single thread in the thread pool, only one task at a time can be executed, so they will be done sequentially in the order submitted.

The Executors class provides a choice of a few different thread pools backing an executor service. You want Executors.newSingleThreadExecutor().

ExecutorService es = Executors.newSingleThreadExecutor() ;

Submit a series of Runnable or Callable objects. Each represents a task to be executed.

es.submit(  ( ) -> System.out.println( "Hello. " + Instant.now() )  ) ;
es.submit(  ( ) -> System.out.println( "Bonjour. " + Instant.now() )  ) ;
es.submit(  ( ) -> System.out.println( "Aloha. " + Instant.now() )  ) ;
es.submit(  ( ) -> System.out.println( "Ciào. " + Instant.now() )  ) ;
es.submit(  ( ) -> System.out.println( "Shwmai. " + Instant.now() )  ) ;

Optionally, you can capture the Future object returned by each call to submit if you want to track completion of the tasks. (not shown in code above)

See this code run live at IdeOne.com.

Hello. 2019-11-29T09:10:13.426987Z

Bonjour. 2019-11-29T09:10:13.472719Z

Aloha. 2019-11-29T09:10:13.473177Z

Ciào. 2019-11-29T09:10:13.473479Z

Shwmai. 2019-11-29T09:10:13.473974Z

Upvotes: 0

zbig
zbig

Reputation: 3956

You should probably use submit method from ExecutorService to schedule your tasks. Here is a working program that uses single thread executor to run 10 tasks. I casted to ThreadPoolExecutor to monitor thread pool state. You can wait for a single task by calling get on its corresponding Future instance or wait for all the tasks by invoking awaitTermination. If you don't need result from the Future just use Void. Hope it helps.

public class Main {                                                                                                                             
    static class TimingCallable implements Callable<Long> {                                                                                     
        static int MIN_WAIT = 200;                                                                                                              
        @Override                                                                                                                               
        public Long call() {                                                                                                                    
            long start = System.currentTimeMillis();                                                                                            
            try {                                                                                                                               
                Thread.sleep(MIN_WAIT + new Random().nextInt(300));                                                                             
            } catch (InterruptedException e) {                                                                                                  
                //DO NOTHING                                                                                                                    
            }                                                                                                                                   
            return System.currentTimeMillis() - start;                                                                                          
        }                                                                                                                                       
    }                                                                                                                                           

    public static void main(String[] args) throws InterruptedException, ExecutionException {                                                    

        ExecutorService executor =  Executors.newFixedThreadPool(1);                                                                            
        @SuppressWarnings("unchecked")                                                                                                          
        Future<Long>[] futureResults = new Future[10];                                                                                          
        for(int i =0; i < futureResults.length; i++) {                                                                                          
            futureResults[i] = executor.submit(new TimingCallable());                                                                           
            System.out.println(String.format("ActiveCount after submitting %d tasks: ", i+1) + ((ThreadPoolExecutor)executor).getActiveCount());
            System.out.println(String.format("Queue size after submitting %d tasks: ", i+1) + ((ThreadPoolExecutor)executor).getQueue().size());
        }                                                                                                                                       
        Thread.sleep(2000);                                                                                                                     
        System.out.println("ActiveCount after 2 seconds: " + ((ThreadPoolExecutor)executor).getActiveCount());                                  
        System.out.println("Queue size after 2 seconds: " + ((ThreadPoolExecutor)executor).getQueue().size());                                  
        for(int i =0; i < futureResults.length; i++) {                                                                                          
            if (futureResults[i].isDone()) {                                                                                                    
                System.out.println(String.format("%d task is done with execution time: ", i) + futureResults[i].get());                         
            }                                                                                                                                   
        }                                                                                                               //Waiting for the last task to finish
        System.out.println("Waiting for the last task result: " + futureResults[9].get());
        executor.shutdown();
        executor.awaitTermination(10, TimeUnit.SECONDS);                                  
    }                                                                                                                                           
}                                                                                                                                               

Upvotes: 2

Abhishek
Abhishek

Reputation: 271

If you are having only one thread to execute just use LinkedQueue for storing jobs once thread is done with the execution then only it will pick another task.

ThreadPoolExecutor executor = new ThreadPoolExecutor(1, 1,1, TimeUnit.MINUTES, new LinkedBlockingQueue<Runnable>());

Also you can have different strategies if you restricting size

http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/ThreadPoolExecutor.html

Read Rejected tasks

Upvotes: 0

Related Questions