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?
A CountDownLatch
is initialized with a given count. This count is decremented by calls to the countDown()
method. Threads waiting for this count to reach zero can call one of the await()
methods. Calling await()
blocks the thread until the count reaches zero.
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);
in main thread call await()
method to wait and every task completion call 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 {
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 ...
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 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.
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!
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.