Search code examples
javaspringmultithreadingconcurrencymanagedthreadfactory

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. 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?


Solution

  • Since I'm using Spring's ThreadPoolTaskExecutor, I found the below which suited my needs ...

    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