首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 企业软件 > 行业软件 >

多线程施行完后主程序再执行(包括需要子线程返回结果)

2012-08-13 
多线程执行完后主程序再执行(包括需要子线程返回结果)1.这是中间变量c,a线程向容器中添加数据,b线程执行其

多线程执行完后主程序再执行(包括需要子线程返回结果)

1.这是中间变量c,a线程向容器中添加数据,b线程执行其他,在主线程判断c是否为空

//判断是否读取完毕
??while(true){
???if(ShareData.isFinish()) {
????break ;
???}
??}

注:此方法,需要知道a线程执行的速度与c线程执行的速度快慢,必须是a的速度大于b的速度

?

2.使用线程阻塞方法join

?public static void main(String[] args) throws InterruptedException{
??TestMain tm = new TestMain();
??Thread t = new Thread(tm);
??t.start();
??t.join();
??System.out.println("main");
?}

注:此方法只能感知一个线程的过程不能判断多个线程的情况

?

3.利用CountDownLatch

?

//------主线程

int threadNum = 5; //线程数
//定义正在运行的线程数
CountDownLatch runningThreadNum = new CountDownLatch(threadNum);
System.out.println(Thread.currentThread().getName()+"-start");
//创建多个子线程
?for (int i = 0; i < threadNum; i++) {
???????new SubThread(runningThreadNum).start();
?}
//等待子线程都执行完了再执行主线程剩下的动作
runningThreadNum.await();

?

//------子线程

?public class SubThread extends Thread{
????? //子线程记数器,记载着运行的线程数
???? private CountDownLatch runningThreadNum;
????? public SubThread(CountDownLatch runningThreadNum){
???????? this.runningThreadNum = runningThreadNum;
???? }
???? @Override
???? public void run() {
???????? ---子程序运行代码---

???????? runningThreadNum.countDown();//正在运行的线程数减一
???? }
}

?

如果需要知道子线程返回结果的则考虑使用线程池

1.实例一

package FutureTaskTest;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;
/** * 测试FutureTask的用法,如果不想分支线程阻塞主线程,又想取得分支线程的执行结果,就用FutureTask
?* * * @author Administrator * */
public class FutureTaskTest {
?/**? * @param args? */
?public static void main(String[] args) {
??CountNum cn = new CountNum(0);?
??//FutureTask<Integer> 这里的表示返回的是Integer?
??FutureTask<Integer> ft = new FutureTask<Integer>(cn);?
??Thread td = new Thread(ft);?
??System.out.println("futureTask开始执行计算:" + System.currentTimeMillis());
??td.start();?
??System.out.println("main 主线程可以做些其他事情:" + System.currentTimeMillis());
??try {??
???// futureTask的get方法会阻塞,知道可以取得结果为止??
???Integer result = ft.get();??
???System.out.println("计算的结果是:" + result);
???} catch (InterruptedException e) {
????e.printStackTrace();?
???} catch (ExecutionException e) {
????e.printStackTrace();
???}
???System.out.println("取得分支线程执行的结果后,主线程可以继续处理其他事项");
??}
?}


class CountNum implements Callable {
?private Integer sum;
?public CountNum(Integer sum) {
??this.sum = sum;
?}

?public Object call() throws Exception {
??for (int i = 0; i < 100; i++) {
???sum = sum + i;
??}
??// 休眠5秒钟,观察主线程行为,预期的结果是主线程会继续执行,到要取得FutureTask的结果是等待直至完成。
??Thread.sleep(3000);?
??System.out.println("futureTask 执行完成" + System.currentTimeMillis());
??return sum;
?}
}

2.实例二

package FutureTaskTest;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.FutureTask;

/**
?* * 测试多核时代,充分的利用CPU来运算数据,并且处理返回的结果,学习API专用 * * @author Administrator *
?*/
public class FutureTaskAndExecutor {
?/** * @param args */
?public static void main(String[] args) {
??List<FutureTask<Integer>> list = new ArrayList<FutureTask<Integer>>();
??// 创建线程池,线程池的大小和List.size没有啥必然的关系,一般的原则是<=list.size,多出来浪费不好
??ExecutorService exec = Executors.newFixedThreadPool(5);
??for (int i = 10; i < 20; i++) {
???// 创建对象
???FutureTask<Integer> ft = new FutureTask<Integer>(new GetSum(i));
???// 添加到list,方便后面取得结果
???list.add(ft);
???// 一个个提交给线程池,当然也可以一次性的提交给线程池,exec.invokeAll(list);
???exec.submit(ft);
??} // 开始统计结果
??Integer total = 0;
??for (FutureTask<Integer> tempFt : list) {
???try {
????total = total + tempFt.get();
???} catch (InterruptedException e) {
????e.printStackTrace();
???} catch (ExecutionException e) {
????e.printStackTrace();
???}
??} // 处理完毕,一定要记住关闭线程池,这个不能在统计之前关闭,因为如果线程多的话,执行中的可能被打断
??exec.shutdown();
??System.out.println("多线程计算后的总结果是:" + total);
?}
}

/** * 这个类很简单,就是统计下简单的加法(从1 到total) * * @author Administrator * */
class GetSum implements Callable {
?private Integer total;
?private Integer sum = 0;

?public GetSum(Integer total) {
??this.total = total;
?}

?public Object call() throws Exception {
??for (int i = 1; i < total + 1; i++) {
???sum = sum + i;
??}
??System.out.println(Thread.currentThread().getName() + " sum:" + sum);
??return sum;
?}
}

?

附件为3个实例

原理图参考:

线程池学习:http://www.cnblogs.com/jersey/archive/2011/03/30/2000231.html

热点排行