java 线程执行完毕_java多线程实现主线程等待所有子线程执行完毕

该博客介绍了一个Java线程框架的实现,允许主线程等待所有子线程执行完毕。通过组合设计模式,作者创建了ThreadSuite类,它管理一组ThreadUnit对象,每个ThreadUnit包装一个线程。ThreadSuite的execute方法启动子线程并在它们完成后等待。通过示例代码展示了两种不同的调用方式,展示了线程执行的不同顺序和同步效果。
摘要由CSDN通过智能技术生成

最近项目中用到线程框架,需要主线程等待所有子线程执行完毕,小编突发奇想,结合设计模式中的复合模式和装饰模式写了这个deamo,这个例子最大的特点是,它不但可以实现最基本的需求,它还拥有像junit一样灵活的使用方法。

以下是源代码和详解:

importjava.util.List;

importjava.util.Vector;

publicclassThreadSuiteextendsThread {

privateList threadUnits =newVector();

privateintthreadCount =0;

privatebooleanwaitEnable =true;

privatelongtimeout =0;

private boolean excuteEnable = true;

publicThreadSuite() {

}

publicThreadSuite(longtimeout) {

this.timeout = timeout;

}

publicThreadSuite(String threadName) {

super(threadName);

}

publicThreadSuite(String threadName,longtimeout) {

super(threadName);

this.timeout = timeout;

}

@Override

publicvoidrun() {

synchronized(this) {

for(ThreadUnit threadUnit : threadUnits) {

if (!threadUnit.isAlive()) {

threadUnit.start();

}

}

if(waitEnable) {

try{

this.wait(timeout);

}catch(InterruptedException e) {

e.printStackTrace();

}

}

}

}

publicsynchronizedvoidadd(ThreadUnit threadUnit) {

threadCount++;

threadUnit.setThreadSuite(this);

threadUnits.add(threadUnit);

}

publicsynchronizedvoidanotice() {

threadCount--;

if(threadCount <1) {

waitEnable =false;

this.notify();

}else{

waitEnable =true;

}

}

publicvoidexcute() {

if (excuteEnable) {

excuteEnable = false;

this.run();

}

}

}

publicclassThreadUnitextendsThread {

privateThreadSuite threadSuite =null;

privateThread thread =null;

publicThreadUnit(Thread thread) {

this.thread = thread;

}

@Override

publicvoidrun() {

try{

this.thread.run();

}catch(Exception e) {

}finally{

if (threadSuite != null) {

threadSuite.anotice();

}

}

}

publicvoidsetThreadSuite(ThreadSuite threadSuite) {

this.threadSuite = threadSuite;

}

}

importjava.util.Random;

publicclassThreadTestextendsThread {

privateRandom random =newRandom();

publicThreadTest(String threadName) {

super(threadName);

}

@Override

publicvoidrun() {

System.out.println(newStringBuffer("Thread:    ").append(

this.getName()).append("       begin."));

try{

Thread.sleep(random.nextInt(1000) +2000);

}catch(InterruptedException e) {

}

System.out.println(newStringBuffer("Thread:    ").append(

this.getName()).append(" end."));

}

}

importjava.util.ArrayList;

importjava.util.List;

publicclassProgram {

publicstaticvoidmain(String[] args) {

List list =newArrayList();

ThreadSuite ts1 = getThreadSuite("a",5);

ThreadSuite ts2 = getThreadSuite("b",5);

list.add(newThreadUnit(ts1));

list.add(newThreadUnit(ts2));

ThreadSuite threadSuite =newThreadSuite();

for(ThreadUnit tu : list) {

threadSuite.add(tu);

}

//      threadSuite.excute();

ts1.excute();

ts2.excute();

System.out.println("main end.");

}

publicstaticThreadSuite getThreadSuite(String threadMark,intthreadCount) {

List list =newArrayList();

for(inti =1; i <= threadCount; i++) {

list.add(newThreadUnit(newThreadTest(threadMark + i)));

}

ThreadSuite threadSuite =newThreadSuite();

for(ThreadUnit tu : list) {

threadSuite.add(tu);

}

returnthreadSuite;

}

}

如果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 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.

main 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()方法将不会被调用。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值