主线程等待线程池结束

http://dongdong1314.blog.51cto.com/389953/224932/


所有SynchronousQueue,它将任务直接提交给线程而不保持它们。在此,如果不存在可用于立即运行任务的线程,则试图把任务加入队列将失败,因此会构造一个新的线程。此策略可以避免在处理可能具有内部依赖性的请求集时出现锁。直接提交通常要求无界 maximumPoolSizes 以避免拒绝新提交的任务。当命令以超过队列所能处理的平均数连续到达时,此策略允许无界线程具有增长的可能性。

无界队列。使用无界队列(例如,不具有预定义容量的 ArrayBlockingQueue)有助于防止资源耗尽,但是可能较难调整和控制。队列大小和最大池大小可能需要相互折衷:使用大型队列和小型池可以最大限度地降低 CPU 使用率、操作系统资源和上下文切换开销,但是可能导致人工降低吞吐量。如果任务频繁阻塞(例如,如果它们是 I/O 边界),则系统可能为超过您许可的更多线程安排时间。使用小型队列通常要求较大的池大小,CPU 使用率较高,但是可能遇到不可接受的调度开销,这样也会降低吞吐量. Above from Javadoc1.6

创建线程池,有多种构造函数。如下两种:
/*public ThreadPoolExecutor(int corePoolSize,
int maximumPoolSize,
long keepAliveTime, TimeUnit unit,
BlockingQueue<Runnable> workQueue,
RejectedExecutionHandler handler)
*/

ThreadPoolExecutor threadPool = newThreadPoolExecutor(5, 5, 3,
TimeUnit.SECONDS, newArrayBlockingQueue<Runnable>(100),
newThreadPoolExecutor.AbortPolicy());

/*public ThreadPoolExecutor(int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue<Runnable> workQueue)*/

ThreadPoolExecutor threadPool2 = newThreadPoolExecutor(5, 8, 1,
TimeUnit.SECONDS, newLinkedBlockingQueue<Runnable>());
使用LinkedBlockingQueue,即不限队列大小,这时 maximumPoolSize 无效。池中线程数最多为 corePoolSize

下面想要完成这样的功能:
主线程在线程池中所有线程结束后才继续执行或结束。
importjava.util.concurrent.LinkedBlockingQueue;
importjava.util.concurrent.ThreadPoolExecutor;
importjava.util.concurrent.TimeUnit;


public classTestThreadPool {
public static voidmain(String[] args) {

System.out.println( "main thread started!");
/*public ThreadPoolExecutor(int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue<Runnable> workQueue)*/

ThreadPoolExecutor threadPool2 = newThreadPoolExecutor(5, 8, 1,
TimeUnit.SECONDS, newLinkedBlockingQueue<Runnable>());
for( inti = 0; i < 10; i++) {
threadPool2.execute( newTask(i));
}
threadPool2.shutdown(); //关闭后不能加入新线程,队列中的线程则依次执行完
while(threadPool2.getPoolSize()!=0);
System.out.println( "main thread end!");
}
}

classTask implementsRunnable{
intcount;
Task( inti){
this.count = i;
}
public voidrun() {
try{
System.out.println( "in thread "+count);
Thread.sleep(10000);
} catch(InterruptedException e) {
e.printStackTrace();
}

System.out.println( "thread "+count+ " end!");
}
}
/*
main thread started!
in thread 1
in thread 0
in thread 2
in thread 3
in thread 4
thread 1 end!
in thread 5
thread 3 end!
in thread 6
thread 2 end!
in thread 7
thread 0 end!
in thread 8
thread 4 end!
in thread 9
thread 5 end!
thread 8 end!
thread 7 end!
thread 6 end!
thread 9 end!
main thread end!
*/
采用的是getPoolSize()返回当前池中的线程数,程序也说明shutdown虽然关闭线程池操作,但只是不加入新线程,而线程池队列中的线程仍将继续执行完成后,才会最后关闭。因此在池中线程未结束时当前线程数不为0.

原来使用thread.join(),在不用线程池时很容易使用,join()似乎要在thread.start()后才能有效,而线程池则直接用threadPool.execute(runnable or thread),用join()无效。
for( inti = 0; i < 10; i++) {
Thread t = newThread( newTask(i), "thread "+ i);
threadPool2.execute( newTask(i));
//t.start();
try{
t.join(); //never effective
} catch(InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
threadPool2.shutdown(); //关闭后不能加入新线程,队列中的线程则依次执行完
//threadPool2.shutdownNow(); //立即中断停止线程执行,返回等待执行的任务列表
System.out.println( "main thread end!");
/*
main thread started!
in thread 0
in thread 1
main thread end!
in thread 2
in thread 3
in thread 4
thread 1 end!
in thread 5
thread 0 end!
in thread 6
thread 4 end!
in thread 7
thread 3 end!
in thread 8
thread 2 end!
in thread 9
thread 5 end!
thread 6 end!
thread 9 end!
thread 8 end!
thread 7 end!
*/

今天发现threadPoolExecutor.isTerminated()可以代替比较,该函数表示如果关闭后所有任务都已完成,则返回 true 。另一函数threadPoolExecutor.isTerminating()则表示如果此执行程序处于在 shutdown shutdownNow 之后正在终止但尚未完全终止的过程中,则返回 true。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值