希望ThreadPoolExecutor能够即时执行任务

时间:2014-07-02 08:45:35

标签: java executorservice threadpoolexecutor

我有一个ThreadPoolExecutor,其中一个线程将用于批处理,所以在将新任务分配给执行程序之前我必须等待先前的任务完成,我这样做取决于活动作业的值,但仔细观察我发现,执行者不会立即执行任务。

这对我造成的问题是我准备提供下一批但第一项任务尚未开始,因此活动作业的价值为0.

如何立即执行任务?我也可以使用任何其他执行者或方式来做到这一点。

3 个答案:

答案 0 :(得分:1)

您应该使用submit中的ExecutorService方法安排任务。这是一个使用单线程执行程序来运行10个任务的工作程序。我转换为ThreadPoolExecutor来监视线程池状态。您可以通过在相应的get实例上调用Future来等待单个任务,也可以通过调用awaitTermination等待所有任务。如果您不需要Future的结果,请使用Void。希望它有所帮助。

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

答案 1 :(得分:0)

如果您只有一个线程要执行,只需使用LinkedQueue存储作业一旦线程完成执行,那么只会选择另一个任务。

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

如果限制尺寸

,也可以有不同的策略

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

阅读已拒绝的任务

答案 2 :(得分:0)

单线程池执行程序服务

显然,您希望立即按照提交的顺序运行多个任务。

非常简单:使用由单个线程支持的 executor service 。执行程序在等待较早的任务完成时会缓冲任务。在线程池中只有一个线程时,一次只能执行一个任务,因此将按照提交的顺序依次执行。

Executors类提供了一些支持执行程序服务的不同线程池的选择。您需要Executors.newSingleThreadExecutor()

ExecutorService es = Executors.newSingleThreadExecutor() ;

提交一系列RunnableCallable对象。每个代表要执行的任务。

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

(可选)如果要跟踪任务的完成情况,则可以捕获每次调用submit返回的Future对象。 (上面的代码中未显示)

请参阅此code run live at IdeOne.com

  

你好2019-11-29T09:10:13.426987Z

     

卓悦。 2019-11-29T09:10:13.472719Z

     

喂。 2019-11-29T09:10:13.473177Z

     

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

     

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