繁体   English   中英

等待线程在java中的线程池中可用

[英]Wait for thread to be available in the thread pool in java

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

拥有 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() 的调用返回时,池中的一个线程理论上是可用的,但它会立即被执行程序重用以运行下一个等待任务。

这是一个任务示例,它使用 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();

    }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM