简体   繁体   English

如何等待线程工厂完成所有任务的执行?

[英]How do I wait for my thread factory to finish executing all its tasks?

I'm using Spring 4.3.8.RELEASE with Java 7. I want to create a thread factory to help manage certain workers in my application. 我正在Java 7中使用Spring 4.3.8.RELEASE,我想创建一个线程工厂来帮助管理应用程序中的某些工作程序。 I declare my thread factory like so 我这样声明我的线程工厂

<bean id="myprojectThreadFactory" class="org.springframework.scheduling.concurrent.CustomizableThreadFactory">
    <constructor-arg value="prefix-"/>
</bean>
<bean id="myprojectTaskExecutor" class="org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor">
    <property name="threadFactory" ref="myprojectThreadFactory"/>
    <property name="corePoolSize" value="${myproject.core.thread.pool.size}" />
    <property name="maxPoolSize" value="${myproject.max.thread.pool.size}" />
</bean>

However, I'm having trouble "join"ing on the threads. 但是,我无法在线程上“加入”。 That is, I want to wait for all work to be completed before continuing with a certain task so I have 也就是说,我要等待所有工作完成后再继续执行某项任务,因此我可以

    m_importEventsWorker.work();
    m_threadExecutor.shutdown();
    System.out.println("done.");

in which my thread pool is executed like so 我的线程池像这样执行

public void work(final MyWorkUnit pmyprojectOrg)
{
    final List<MyWorkUnit> allOrgs = new ArrayList<MyWorkUnit>();
    if (pmyprojectOrg != null)
    {
        processData(pmyprojectOrg.getmyprojectOrgId());
    } else { 
        allOrgs.addAll(m_myprojectSvc.findAllWithNonEmptyTokens());
        // Cue up threads to execute
        for (final MyWorkUnit myprojectOrg : allOrgs)
        {
            m_threadExecutor.execute(new Thread(new Runnable(){
                @Override
                public void run()
                {
                    System.out.println("started.");
                    processData(myprojectOrg.getmyprojectOrgId());
                }
            }));
        }   // for

Yet what gets printed out is 然而,打印出来的是

done.
started.
started.

So clearly I'm not waiting. 所以很明显我没有等。 What's the right way to wait for my threads to finish working? 等待我的线程完成工作的正确方法是什么?

A CountDownLatch is initialized with a given count. CountDownLatch用给定的计数初始化。 This count is decremented by calls to the countDown() method. 通过调用countDown()方法可减少此计数。 Threads waiting for this count to reach zero can call one of the await() methods. 等待该计数达到零的线程可以调用await()方法之一。 Calling await() blocks the thread until the count reaches zero. 调用await()阻塞线程,直到计数达到零为止。

You can use CountDownLatch to main thread to wait for completion all the task.You can declare CountDownLatch with size as number of task CountDownLatch latch = new CountDownLatch(3); 您可以使用CountDownLatch到主线程来等待所有任务完成。您可以声明CountDownLatch ,其大小为任务数CountDownLatch latch = new CountDownLatch(3); in main thread call await() method to wait and every task completion call countDown() 在主线程中调用await()方法以等待,每个任务完成调用countDown()

public void work(final MyWorkUnit pmyprojectOrg)
{
    final List<MyWorkUnit> allOrgs = new ArrayList<MyWorkUnit>();
    if (pmyprojectOrg != null)
    {
        processData(pmyprojectOrg.getmyprojectOrgId());
    } else { 
        allOrgs.addAll(m_myprojectSvc.findAllWithNonEmptyTokens());

        CountDownLatch latch = new CountDownLatch(allOrgs.size());

        // Cue up threads to execute
        for (final MyWorkUnit myprojectOrg : allOrgs)
        {
            m_threadExecutor.execute(new Thread(new Runnable(){
                @Override
                public void run()
                {
                    System.out.println("started.");
                    processData(myprojectOrg.getmyprojectOrgId());
                   latch.countDown();
                }
            }));
        }  
       //After for loop
       latch.await();      

Example: 例:

CountDownLatch latch = new CountDownLatch(3);

Waiter      waiter      = new Waiter(latch);
Decrementer decrementer = new Decrementer(latch);

new Thread(waiter)     .start();
new Thread(decrementer).start();

public class Waiter implements Runnable{

    CountDownLatch latch = null;

    public Waiter(CountDownLatch latch) {
        this.latch = latch;
    }

    public void run() {
        try {
            latch.await();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        System.out.println("Waiter Released");
    }
}

public class Decrementer implements Runnable { 公共类Decrementer实现Runnable {

CountDownLatch latch = null;

public Decrementer(CountDownLatch latch) {
    this.latch = latch;
}



 public void run() {

        try {
            Thread.sleep(1000);
            this.latch.countDown();

            Thread.sleep(1000);
            this.latch.countDown();

            Thread.sleep(1000);
            this.latch.countDown();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

Since I'm using Spring's ThreadPoolTaskExecutor, I found the below which suited my needs ... 由于我使用的是Spring的ThreadPoolTask​​Executor,因此我发现了以下适合自己的需求...

protected void waitForThreadPool(final ThreadPoolTaskExecutor threadPoolExecutor)
{
    threadPoolExecutor.setWaitForTasksToCompleteOnShutdown(true);
    threadPoolExecutor.shutdown();    
    try {
        threadPoolExecutor.getThreadPoolExecutor().awaitTermination(30, TimeUnit.SECONDS);
    } catch (IllegalStateException e) {
      e.printStackTrace();
    } catch (InterruptedException e) {
      e.printStackTrace();
    }
}   // waitForThreadPool

You can create a fixed thread pool by using ExecutorService and check whether the pool size is empty or not: 您可以使用ExecutorService创建固定的线程池,并检查池的大小是否为空:

ExecutorService executor = Executors.newFixedThreadPool(50);

If you run your tasks by using this executor and check the thread pool size periodically by using @Scheduled fixedRate or fixedDelay, you can see if they are finished or not. 如果使用此执行程序运行任务,并使用@Scheduled fixedRate或fixedDelay定期检查线程池大小,则可以查看它们是否已完成。

ThreadPoolExecutor poolInfo = (ThreadPoolExecutor) executor;
Integer activeTaskCount = poolInfo.getActiveCount();

if(activeTaskCount = 0) {
    //If it is 0, it means threads are waiting for tasks, they have no assigned tasks.
    //Do whatever you want here!
}

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

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