Java 如何判断java线程池执行完毕所有任务是否执行完毕

如何判断线程池处理完任务 - ITeye问答
用的是ThreadPoolExecutor,做法是提交一个任务后不管,可以提交多个任务.最后要等任务全部完成了在去调用一个方法,我原来的做法是:
public boolean isEndTask() {
while (true) {
if (this.executor.getActiveCount() == 0) {
void synBackup(String fn, IProgress pro) {
if (isEndTask()) //如果线程池处理完毕,就干别的事情...,这个方法一定会返回true的.
也就是调用synBackup(String fn, IProgress pro)这个方法的时候,一定使线程池里面的任务完成了我才可以干其他的事情.
本来不用什么线程池,也就是单线程来处理这个任务只需要17秒的,可是我用线程池后居然需要18秒,郁闷,没有体现速度.
不知道是我这样判断任务处理完毕的方法不对,还是构造线程池的时候参数设置的不是很合理,请指教指教!!
如果你的CPU是单核的,那么用线程池跟用单线程是没有差别的(从执行时间来说)。
已解决问题
未解决问题Java(195)
多线程高并发(2)
void shutdown()
启动一次顺序关闭,执行以前提交的任务,但不接受新任务。如果已经关闭,则调用没有其他作用。
抛出:&- 如果安全管理器存在并且关闭,此 ExecutorService 可能操作某些不允许调用者修改的线程(因为它没有保持(&modifyThread&)),或者安全管理器的&checkAccess&方法拒绝访问。
isTerminated
boolean isTerminated()
如果关闭后所有任务都已完成,则返回&true。注意,除非首先调用&shutdown&或&shutdownNow,否则&isTerminated&永不为&true。
如果关闭后所有任务都已完成,则返回&true
package javatest.executorservicetest.executorservicetest1;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
* Java如何判断线程池所有任务是否执行完毕?
* Created by Lovell on 17/11/2016.
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
public class ExecutorServiceTest {
public static void main(String args[]) throws InterruptedException {
ExecutorService exe = Executors.newFixedThreadPool(50);
for (int i = 1; i &= 5; i++) {
exe.execute(new SubThread(i));
// 关闭线程池
exe.shutdown();
// 该方法在加入线程队列的线程执行完之前不会执行
while (true) {
// 所有任务全部执行终止
if (exe.isTerminated()) { // 当shutdown()或者shutdownNow()执行了之后才会执行,并返回true。
System.out.println(&结束了!&);
Thread.sleep(200);
package javatest.executorservicetest.executorsevicetest2;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
* Created by Lovell on 17/11/2016.
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
public class ExecutorServiceTest2 {
public static void moreThread() {
ExecutorService exe = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors() * 2 + 1);
int threadNum = 0;
for (int i = 0; i & 10; i++) {
threadNum++;
final int currentThreadNum = threadNum;
exe.execute(new Runnable() {
public void run() {
System.out.println(&子线程[& + currentThreadNum + &]开启&);
Thread.sleep(1000 * 10);
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
System.out.println(&子线程[& + currentThreadNum + &]结束&);
System.out.println(&已经开启所有的子线程&);
exe.shutdown();
System.out.println(&shutdown():启动一次顺序关闭,执行以前提交的任务,但不接受新任务。&);
while(true){
if(exe.isTerminated()){
System.out.println(&所有的子线程都结束了!&);
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
System.out.println(&主线程结束&);
public static void main(String[] args) {
moreThread();
子线程[1]开启
子线程[2]开启
子线程[3]开启
子线程[4]开启
子线程[5]开启
子线程[6]开启
子线程[7]开启
子线程[8]开启
子线程[9]开启
已经开启所有的子线程
shutdown():启动一次顺序关闭,执行以前提交的任务,但不接受新任务。
子线程[1]结束
子线程[3]结束
子线程[10]开启
子线程[2]结束
子线程[4]结束
子线程[5]结束
子线程[7]结束
子线程[8]结束
子线程[6]结束
子线程[9]结束
子线程[10]结束
所有的子线程都结束了!
主线程结束
参考:http://blog.csdn.net/truong/article/details/
http://blog.csdn.net/lisheng/article/details/
&&相关文章推荐
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:806331次
积分:12785
积分:12785
排名:第1121名
原创:415篇
转载:584篇
评论:49条
(7)(9)(5)(4)(14)(15)(5)(6)(33)(90)(43)(161)(112)(120)(140)(116)(88)(36)(1)
(window.slotbydup = window.slotbydup || []).push({
id: '4740887',
container: s,
size: '250,250',
display: 'inlay-fix'用户名:zhipei_my
访问量:6940
注册日期:
阅读量:1297
阅读量:3317
阅读量:461474
阅读量:1145842
51CTO推荐博文
&&&&&& 最近项目中用到线程框架,需要主线程等待所有子线程执行完毕,小编突发奇想,结合设计模式中的复合模式和装饰模式写了这个deamo,这个例子最大的特点是,它不但可以实现最基本的需求,它还拥有像junit一样灵活的使用方法。
&以下是源代码和详解:
import&java.util.L &import&java.util.V &&public&class&ThreadSuite&extends&Thread&{ &&&&&private&List&ThreadUnit&&threadUnits&=&new&Vector&ThreadUnit&(); &&&&&private&int&threadCount&=&0; &&&&&private&boolean&waitEnable&=&true; &&&&&private&long&timeout&=&0;
private boolean excuteEnable =&&&&&public&ThreadSuite()&{ &&&&&} &&&&&public&ThreadSuite(long&timeout)&{ &&&&&&&&&this.timeout&=& &&&&&} &&&&&public&ThreadSuite(String&threadName)&{ &&&&&&&&&super(threadName); &&&&&} &&&&&public&ThreadSuite(String&threadName,&long&timeout)&{ &&&&&&&&&super(threadName); &&&&&&&&&this.timeout&=& &&&&&} &&&&&@Override&&&&&public&void&run()&{ &&&&&&&&&synchronized&(this)&{ &&&&&&&&&&&&&for&(ThreadUnit&threadUnit&:&threadUnits)&{ &&&&&&&&&&&&&&&&&if (!threadUnit.isAlive()) {&&&&&
threadUnit.start();&&&&
}&&&&&&&&&&&&} &&&&&&&&&&&&&if&(waitEnable)&{ &&&&&&&&&&&&&&&&&try&{ &&&&&&&&&&&&&&&&&&&&&this.wait(timeout); &&&&&&&&&&&&&&&&&}&catch&(InterruptedException&e)&{ &&&&&&&&&&&&&&&&&&&&&e.printStackTrace(); &&&&&&&&&&&&&&&&&} &&&&&&&&&&&&&} &&&&&&&&&} &&&&&} &&&&&public&synchronized&void&add(ThreadUnit&threadUnit)&{ &&&&&&&&&threadCount++; &&&&&&&&&threadUnit.setThreadSuite(this); &&&&&&&&&threadUnits.add(threadUnit); &&&&&} &&&&&public&synchronized&void&anotice()&{ &&&&&&&&&threadCount--; &&&&&&&&&if&(threadCount&&&1)&{ &&&&&&&&&&&&&waitEnable&=&false; &&&&&&&&&&&&&this.notify(); &&&&&&&&&}&else&{ &&&&&&&&&&&&&waitEnable&=&true; &&&&&&&&&} &&&&&} &&&&&public&void&excute()&{ &&&&&&&&&if (excuteEnable) {&&&
excuteEnable =&&&
this.run();&&
}&&&&} &} &&public&class&ThreadUnit&extends&Thread&{ &&&&&private&ThreadSuite&threadSuite&=&null; &&&&&private&Thread&thread&=&null; &&&&&public&ThreadUnit(Thread&thread)&{ &&&&&&&&&this.thread&=& &&&&&} &&&&&@Override&&&&&public&void&run()&{ &&&&&&&&&try&{ &&&&&&&&&&&&&this.thread.run(); &&&&&&&&&}&catch&(Exception&e)&{ &&&&&&&&&}&finally&{ &&&&&&&&&&&&&if (threadSuite != null) {&&&
&threadSuite.anotice();&&&
}&&&&&&&&} &&&&&} &&&&&public&void&setThreadSuite(ThreadSuite&threadSuite)&{ &&&&&&&&&this.threadSuite&=&threadS &&&&&} &} &&import&java.util.R &public&class&ThreadTest&extends&Thread&{ &&&&&private&Random&random&=&new&Random(); &&&&&public&ThreadTest(String&threadName)&{ &&&&&&&&&super(threadName); &&&&&} &&&&&@Override&&&&&public&void&run()&{ &&&&&&&&&System.out.println(new&StringBuffer(&Thread:&&&&&).append( &&&&&&&&&&&&&&&&&this.getName()).append(&&&&&&&&begin.&)); &&&&&&&&&try&{ &&&&&&&&&&&&&&Thread.sleep(random.nextInt(1000)&+&2000); &&&&&&&&&}&catch&(InterruptedException&e)&{ &&&&&&&&&} &&&&&&&&&System.out.println(new&StringBuffer(&Thread:&&&&&).append( &&&&&&&&&&&&&&&&&this.getName()).append(&&end.&)); &&&&&} &} &&import&java.util.ArrayL &import&java.util.L &public&class&Program&{ &&&&&public&static&void&main(String[]&args)&{ &&&&&&&&&List&ThreadUnit&&list&=&new&ArrayList&ThreadUnit&(); &&&&&&&&&ThreadSuite&ts1&=&getThreadSuite(&a&,&5); &&&&&&&&&ThreadSuite&ts2&=&getThreadSuite(&b&,&5); &&&&&&&&&list.add(new&ThreadUnit(ts1)); &&&&&&&&&list.add(new&ThreadUnit(ts2)); &&&&&&&&&ThreadSuite&threadSuite&=&new&ThreadSuite(); &&&&&&&&&for&(ThreadUnit&tu&:&list)&{ &&&&&&&&&&&&&threadSuite.add(tu); &&&&&&&&&} &&&&&&&&&&ts1.excute(); &&&&&&&&&ts2.excute(); &&&&&&&&&System.out.println(&main&end.&); &&&&&} &&&&&public&static&ThreadSuite&getThreadSuite(String&threadMark,int&threadCount)&{ &&&&&&&&&List&ThreadUnit&&list&=&new&ArrayList&ThreadUnit&(); &&&&&&&&&for&(int&i&=&1;&i&&=&threadC&i++)&{ &&&&&&&&&&&&&list.add(new&ThreadUnit(new&ThreadTest(threadMark&+&i))); &&&&&&&&&} &&&&&&&&&ThreadSuite&threadSuite&=&new&ThreadSuite(); &&&&&&&&&for&(ThreadUnit&tu&:&list)&{ &&&&&&&&&&&&&threadSuite.add(tu); &&&&&&&&&} &&&&&&&&&return&threadS &&&&&} &}&
&如果main方法中最后几行的代码是这样的:
//&&&&&&threadSuite.excute(); &&&&&&&&&ts1.excute(); &&&&&&&&&ts2.excute(); &&&&&&&&&System.out.println(&main&end.&);&
则执行结果为:
Thread:&&& a2&&&&&& begin.
Thread:&&& a1&&&&&& begin.
Thread:&&& a3&&&&&& begin.
Thread:&&& a5&&&&&& begin.
Thread:&&& a4&&&&&& begin.
Thread:&&& a2 end.
Thread:&&& a5 end.
Thread:&&& a4 end.
Thread:&&& a1 end.
Thread:&&& a3 end.
Thread:&&& b1&&&&&& begin.
Thread:&&& b3&&&&&& begin.
Thread:&&& b5&&&&&& begin.
Thread:&&& b2&&&&&& begin.
Thread:&&& b4&&&&&& begin.
Thread:&&& b4 end.
Thread:&&& b1 end.
Thread:&&& b2 end.
Thread:&&& b3 end.
Thread:&&& b5 end.
&如果main方法中最后几行的代码是这样的:
&&&&&&&&threadSuite.excute(); &//&&&&&&ts1.excute(); &//&&&&&&ts2.excute(); &&&&&&&&&System.out.println(&main&end.&);&
则执行结果为:
Thread:&&& b1&&&&&& begin.
Thread:&&& a1&&&&&& begin.
Thread:&&& a2&&&&&& begin.
Thread:&&& a3&&&&&& begin.
Thread:&&& a4&&&&&& begin.
Thread:&&& a5&&&&&& begin.
Thread:&&& b2&&&&&& begin.
Thread:&&& b3&&&&&& begin.
Thread:&&& b4&&&&&& begin.
Thread:&&& b5&&&&&& begin.
Thread:&&& b5 end.
Thread:&&& b4 end.
Thread:&&& b3 end.
Thread:&&& b1 end.
Thread:&&& a1 end.
Thread:&&& a2 end.
Thread:&&& a5 end.
Thread:&&& a4 end.
Thread:&&& b2 end.
Thread:&&& a3 end.
从以上执行结果可以看出:
&&&&&&& ThreadSuite类的excute()方法其实是直接调用了它自身的run方法,并且ThreadSuite线程类会等待所有加入到它的管理队列中的Thread类执行完毕后,它的run方法才会运行完毕。因此,完全可以把ThreadSuite类当成是普通的Thread类对待,这样的话,可以把生成的多个ThreadSuite类实例当作普通线程类经过ThreadUnit类包装后放入新的ThreadSuite类管理队列当中
需要注意的是:
&&&&&& 这个deamo其实也不算是个完全的复合模式,因为子线程是经过ThreadUnit类装饰过的,但是你也完全可以理解为:是ThreadSuite类对Thread类的复合,因为Thread类也是ThreadUnit类的父类,也就是说向上转型。在每一个Thread类实例经过ThreadUnit类包装后并加入到ThreadSuite类管理队列中时,ThreadSuite类会把当前线程计数加1。ThreadUnit类其实是Thread类的一个包装类,它会在加入到它的Thread类实例的run方法运行完毕后调用ThreadSuite类的anotice()方法通知ThreadSuite类自己的线程任务已经完成,并请求线程计数减1,这样的话,ThreadSuite类会判断当前所有的加入到它的管理队列中的线程是否全部执行完毕,如果执行完毕,它会调用自身的notice()方法停止等待。如果加入到ThreadSuite类管理队列中的所有Thread类执行完毕后,ThreadSuite类才调用它自身的wait()方法(这种情况出现的几率很小),这样的话,ThreadSuite类会一直等待下去,直到等待超时,因为已经没有可用的Thread类试图唤醒ThreadSuite类的等待,为了防止这种情况出现,ThreadSuite类引入了waitEnable字段,它的初始值是true,当线程计数小于1的时候,它会被设为false,这样的话,在所有的Thead类执行完毕后,ThreadSuite类的wait()方法将不会被调用。本文出自 “” 博客,谢绝转载!
了这篇文章
类别:┆阅读(0)┆评论(0)
本文收录至博客专题:《》java线程池主线程等待子线程执行完成后再继续处理后面工作_悬赏任务_百度文库
两大类热门资源免费畅读
续费一年阅读会员,立省24元!
java线程池主线程等待子线程执行完成后再继续处理后面工作
我需要一份与标题相关的文档
收到0篇文档
上传优质文档奖励
文库对每周新上传的公开文档进行评选,被评为优质文档可获每篇下载+1奖励。查看
相似悬赏任务判断多线程是否执行完成(afterexecute)
我的图书馆
判断多线程是否执行完成(afterexecute)
思路如下:原文:本人近来需要在servlet里另起线程池,以便控制,因为servlet的线程是不为我们能控制的,所以无奈之下,使用了ThreadPoolExecutor类。 但是有些任务需要在自己创建的线程池里执行完了,servlet的程序才继续执行。 本来想着用join(),但是线程池的线程引用拿不到,如果在线程池里设置成员变量,又会引起线程不安全(事实上,join()了也没用,因为线程池的线程是不会结束的,join()等待是无结果的)。 苦于成员变量不能设置,局部变量又不可以夸类传递。。 方法一:如果用某个变量控制循环等待,可以实现功能,但不是我要的结果,因为这样的主线程并不是挂起,只是不断循环等待的,一样需要耗费资源,如果线程过多会非常浪费资源。 方法二:在执行任务的程序的run()方法的最后用wait/notify,唤醒主线程,真正实现了异步,主线程并不多耗费资源。缺点是不够灵活,例如:更改了执行的任务,就必须在新任务的run()方法后加入唤醒操作,不能做到与任务无关,所以有了第三种方法。 方法三:用wait/notify和挂钩程序及反射机制的应用,实现了线程池间的通信控制。下面的程序就是介绍第三种方法的。主程序(main函数可模拟是servlet的doPost(),只要保证该类线程安全即可):另见CSDN的一个文章,这个文章有代码,实现上述第三种思路答:isEndTask()用while(true){..}来判别所有线程已执行结束,否则程序就不许往下执行.while(true){..}在多线程中是很浪费CPU的,从而使得线程池中各个线程得到很少的CPU机会去执行自己各自的任务。因此影响了线程池的优势的发挥。那如何改进代码呢?我的建议是:1)从ThreadPoolExecutor继承,定制它的回调方法:protected void afterExecute(Runnable r, Throwable t),在该方法的代码中,判getActiveCount() 是不是 0,若是0,则置boolean 型变量hasFinished=并发出notifyAll()通知,通知synBackup()方法所在的线程,hasFinished已为true,它可以开始运行了[主要原因是:synBackup()方法调用了下边的waitForEndTask() 方法,而该方法是用wait()等待线程池所有线程运行结束的。]。2)isEndTask()方法的代码不能是while(true);改为:若没有完成,就wait(),放弃CPU,让CPU宝贵的资源留给线程池中的线程。因此方法名改为waitForEndTask()。代码如下:public void waitForEndTask() {& synchronized(变量hasFinished所在的对象){& while (hasFinished==false) {& try{变量hasFinished所在的对象.wait();}& catch(InterruptedException e){}&&& }& }3)这样设计的目的是:当线程池中线程没有全部运行结束时,synBackup()方法[内部调用了waitForEndTask() ]所有的线程是处于wait()下,不占用宝贵的CPU资源,让CPU资源全部留给了线程池中线程。当线程池中所有的线程全运行结束,才会通过notifyAll()来唤醒synBackup()方法所有的线程继续向下运行。import java.io.*;
import java.util.concurrent.*;
import java.util.*;
class MyThreadPoolExecutor extends ThreadPoolExecutor{
private boolean hasFinish = false;
public MyThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue&Runnable& workQueue, RejectedExecutionHandler handler)
super(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue, handler);
// TODO Auto-generated constructor stub
public MyThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue&Runnable& workQueue, ThreadFactory threadFactory, RejectedExecutionHandler handler)
super(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,
threadFactory, handler);
// TODO Auto-generated constructor stub
public MyThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue&Runnable& workQueue, ThreadFactory threadFactory) {
super(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,
threadFactory);
// TODO Auto-generated constructor stub
public MyThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue&Runnable& workQueue) {
super(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue);
// TODO Auto-generated constructor stub
/* (non-Javadoc)
* @see java.util.concurrent.ThreadPoolExecutor#afterExecute(java.lang.Runnable, java.lang.Throwable)
protected void afterExecute(Runnable r, Throwable t) {
// TODO Auto-generated method stub
super.afterExecute(r, t);
synchronized(this){
System.out.println("自动调用了....afterEx 此时getActiveCount()值:"+this.getActiveCount());
if(this.getActiveCount() == 1)//已执行完任务之后的最后一个线程
this.hasFinish=true;
this.notify();
}// synchronized
public void isEndTask() {
synchronized(this){
while (this.hasFinish==false) {
System.out.println("等待线程池所有任务结束: wait...");
this.wait();
catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
TA的最新馆藏
喜欢该文的人也喜欢}

我要回帖

更多关于 线程池任务执行 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信