【问题标题】:Wait for thread to be available in the thread pool in java等待线程在java中的线程池中可用
【发布时间】:2018-07-24 19:40:42
【问题描述】:

我在 JAVA 中使用 executorservice 进行线程池。有没有一种方法可以让我在执行器服务的线程池中等待线程可用,并且只有在池中有可用线程时才继续

【问题讨论】:

    标签: java threadpool executorservice


    【解决方案1】:

    拥有 ExecutorService 的全部意义在于不关心处理线程,因此您应该避免这样做,除非您有非常具体的理由来跟踪它们的状态。

    您还可以将任意数量的任务添加到池中,执行器将全部运行。

    例如:

    final List<Callable<Boolean>> tasks = new ArrayList<>(10);
    for (int i=0;i<10;i++) tasks.add(()->{
        //something time consuming
        return true;
    });
    
    final ExecutorService executor = Executors.newFixedThreadPool(5);
    List<Future<Boolean> handles = executor.invokeAll(tasks);
    
    for (Future<Boolean> handle : handles) {
        handle.get();
    }
    
    // here all the 10 tasks have been completed by the 5 thread pool
    

    请注意,每次调用 handle.get() 返回时,池中的线程理论上是可用的,但它会立即被执行程序重用以运行下一个等待任务。

    【讨论】:

    • 我有数百万个任务需要执行。我只想等待线程池中的线程可用,然后再向执行器服务添加更多任务
    • 我需要固定的线程池大小,以便我可以在我的任务中使用线程池名称来处理一些事情。我不想在运行时添加或删除线程,我需要固定数量的线程。
    • 这就是为什么我需要修复线程数,因为我在程序中以某种方式使用它的名称。
    • 如果你真的想这样做(专业提示:你不这样做),然后开始提交与线程数一样多的任务,并在每次 handle.get() 返回时添加一个新任务。
    【解决方案2】:

    这是一个使用 ThreadPool 并在等待可用线程的工作过多时让线程提交工作等待的任务示例

    这在列出 [做什么] 成本低且 [做什么] 耗时的情况下很有用。

    例如:

    • 当您运行 CPU 密集型任务并且有大量可用的 CPU 时。
    • 当您运行依赖于多个慢速 API 或数据源的任务时。

    Java ThreadPools 似乎是为开发人员设计的,可以小批量提交工作并等待结果(通过 Future.get 或通过 ThreadPool.shutdown)。阻塞行为没有直接的队列大小控制。我相信这就是@Francesco Rogo 试图向您解释的内容。但是有一些解决方法。我发现自定义线程池以限制工作队列的大小并使提交工作的线程等待更容易。我怀疑你也想要那个。

    package lucas.examples.threadPool;
    
    import java.util.concurrent.LinkedBlockingQueue;
    import java.util.concurrent.ThreadPoolExecutor;
    import java.util.concurrent.TimeUnit;
    
    public class ExampleThreadPool {
    
        public static void main( String[] args ) {
    
            // Example resources:
            //  ThreadLocal<Sql> db001 = new ThreadLocal<Sql>() { protected Sql initialValue() { return DataSource001.instance.get(); }
            //  ThreadLocal<Sql> db002 = new ThreadLocal<Sql>() { protected Sql initialValue() { return DataSource002.instance.get(); }
                
            ThreadPoolExecutor pool = new ThreadPoolExecutor( 
                /*nThreads=*/15, /*nThreads=*/15,  
                0L, TimeUnit.MILLISECONDS, 
                new LinkedBlockingQueue<>( /*work queue size=*/ 1 )
            );
            
            // Setup a thread factory to close the resources  
            pool.setThreadFactory( (r) -> {
                return new Thread( () -> {          
                    r.run();            
                    // Sql.close( db001 ) 
                    // Sql.close( db002 ) 
                });
            } );
                
            // When the work queue is full, make the thread calling pool.execute() to wait 
            pool.setRejectedExecutionHandler( 
                (runnable,executor) -> { 
                    try { 
                        executor.getQueue().put(runnable); 
                    } catch( Exception e ) { 
                        throw new RuntimeException(e); 
                    } 
                } 
            );
    
            // Simulates a work datasource 
            for( int i = 0; i < 1000000; i++ ) {
    
                int i2 = i;
                
                System.out.println( "submit work..." + i2 );
                            
                pool.execute( () ->  {
                    // start parallel processing 
    
                    System.out.println( "begin execution of work..." + i2 );
                    try { Thread.sleep(500); } catch( Exception e ) { }
                    System.out.println( "end execution of work..." + i2 );
    
                    // end parallel processing 
                } );
    
            }
    
            // IMPORTANT: wait all threads to finish the work before ending the program 
            pool.shutdown();
    
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-01-06
      • 1970-01-01
      • 2019-10-08
      • 2015-07-13
      • 2015-08-29
      • 2010-10-16
      • 2013-01-23
      相关资源
      最近更新 更多