`

处理 子线程的返回值

 
阅读更多
package com.jimmy.Thread.ConcurrentTools;

import static java.lang.System.out;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.Callable;
import java.util.concurrent.CompletionService;
import java.util.concurrent.ExecutorCompletionService;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.FutureTask;
import java.util.concurrent.TimeUnit;

class TaskWithResult implements Callable<String>
{
  private int id;

  public TaskWithResult(int id) throws InterruptedException
  {

    this.id = id;
  }

  @Override
  public String call() throws Exception
  {
    TimeUnit.SECONDS.sleep(2);
    return "result of TaskWithResult " + id;
  }
}

public class CallableTest
{
  public static void main(String[] args) throws Exception
  {
//    test1();
    test3();
  }
  
  /**
   * 用 Join()方法等待所有子线程执行完,再收集执行结果
   * @throws Exception
   */
  public static void test2() throws Exception
  {
    List<Thread> list = new ArrayList<Thread>();
    ExecutorService exec = Executors.newCachedThreadPool();
    ArrayList<FutureTask<String>> results = new ArrayList<FutureTask<String>>(); // Future
    // 相当于是用来存放Executor执行的结果的一种容器
    for (int i = 0; i < 10; i++) {
      Callable<String> callable = new TaskWithResult(i);
      FutureTask<String> futureTask = new FutureTask<String>(callable);
      Thread thread = new Thread(futureTask);
      thread.start();
      results.add(futureTask);
      list.add(thread);
    }
    long time0 = System.currentTimeMillis();
    for(Thread thread:list){
      thread.join();
    }
    out.println("共耗时:" + (System.currentTimeMillis()-time0));
    
    String string = null;
    for (FutureTask<String> fs : results) {
      if(fs.isDone()){
        try {
          string = fs.get();
        } catch (Exception e) {
          e.printStackTrace();
        }
        out.println(string);
      }else{
        out.println("is not done!");
      }
    }
    exec.shutdown();
  }

  /**
   * 以BlockingQueue阻塞队列显式的接受子线程的返回值,操控灵活
   * @throws Exception
   */
  public static void test1() throws Exception
  {
    ExecutorService pool = Executors.newCachedThreadPool();
    BlockingQueue<Future<String>> blockingQueue = new ArrayBlockingQueue<Future<String>>(10);
    CompletionService<String> service = new ExecutorCompletionService<String>(pool,blockingQueue);
                                                                         // 相当于是用来存放Executor执行的结果的一种容器
    for (int i = 0; i < 10; i++) {
      Callable<String> callable = new TaskWithResult(i);
      service.submit(callable);
    }
    String string = null;
    int count = 0;
    while(true){
      Future<String> future = blockingQueue.take();
      string = future.get();
      count ++;
      out.println(future.isDone() + "..value:===" + string);
      if(count == 10){
        break;
      }
    }
    pool.shutdown();
  }
  
  /**
   * 此种方式获取子线程的值是最为方便
   * @throws Exception
   */
  public static void test3() throws Exception
  {
    ExecutorService pool = Executors.newCachedThreadPool();
    CompletionService<String> service = new ExecutorCompletionService<String>(pool);
                                                                         // 相当于是用来存放Executor执行的结果的一种容器
    for (int i = 0; i < 10; i++) {
      Callable<String> callable = new TaskWithResult(i);
      service.submit(callable);
    }
    
    String string = null;
    for (int i = 0; i < 10; i++) {
      Future<String> future = service.take();//阻塞模式循环获取队列的值
      string = future.get();
      out.println(string);
    }
    pool.shutdown();
  }
}
分享到:
评论

相关推荐

    多线程机制

    7、 浅析 Java Thread.join() : java多线程实现主线程等待所有子线程执行完毕 16 8、 线程运行中抛出异常的处理 19 9、 Callable 有返回值的线程 20 10、 Callable结合FutureTask的多线程使用(免打扰模式) 24

    c++多线程的创建挂起执行与销毁

    5. 声明并编写线程函数,注意只能有一个参数,且函数的返回值类型也是固定的;函数名可以自定义; DWORD WINAPI ThreadFun(LPVOID pthread);//线程入口函数 6. 在启动按钮的消息处理函数中编写如下代码: thread1....

    黑马安卓基础教程day5 (总共day8)

    48_通过handler和message在子线程里面去更新UI.avi 49_多线程断点下载的实现&界面的更新.avi 50_如何避免掉程序出现anr异常.avi 51_隐式意图和显示意图.avi 52_activity之间传递数据&批量传递数据.avi 53_启动...

    java面试宝典2012版.pdf

    56、子线程循环10次,接着主线程循环100,接着又回到子线程循环10次,接着再回到主线程又循环100,如此循环50次,请写出程序。 57、介绍Collection框架的结构 58、Collection框架中实现比较要实现什么接口 59、...

    linux系统编程之线程.zip

    【练习】:使用pthread_join函数将循环创建的多个子线程回收。 【pthrd_loop_join.c】 pthread_detach函数 实现线程分离 int pthread_detach(pthread_t thread); 成功:0;失败:错误号 线程分离状态:指定该...

    最新Java面试宝典pdf版

    56、子线程循环10次,接着主线程循环100,接着又回到子线程循环10次,接着再回到主线程又循环100,如此循环50次,请写出程序。 38 57、介绍Collection框架的结构 43 58、Collection框架中实现比较要实现什么接口 43 ...

    Java面试笔试资料大全

    56、子线程循环10次,接着主线程循环100,接着又回到子线程循环10次,接着再回到主线程又循环100,如此循环50次,请写出程序。 38 57、介绍Collection框架的结构 43 58、Collection框架中实现比较要实现什么接口 43 ...

    Java面试宝典2010版

    56、子线程循环10次,接着主线程循环100,接着又回到子线程循环10次,接着再回到主线程又循环100,如此循环50次,请写出程序。 57、介绍Collection框架的结构 58、Collection框架中实现比较要实现什么接口 59、...

    Java面试宝典-经典

    56、子线程循环10次,接着主线程循环100,接着又回到子线程循环10次,接着再回到主线程又循环100,如此循环50次,请写出程序。 38 57、介绍Collection框架的结构 43 58、Collection框架中实现比较要实现什么接口 43 ...

    JAVA面试宝典2010

    56、子线程循环10次,接着主线程循环100,接着又回到子线程循环10次,接着再回到主线程又循环100,如此循环50次,请写出程序。 38 57、介绍Collection框架的结构 43 58、Collection框架中实现比较要实现什么接口 43 ...

    java面试题大全(2012版)

    56、子线程循环10次,接着主线程循环100,接着又回到子线程循环10次,接着再回到主线程又循环100,如此循环50次,请写出程序。 38 57、介绍Collection框架的结构 43 58、Collection框架中实现比较要实现什么接口 43 ...

    Java面试宝典2012版

    56、子线程循环10次,接着主线程循环100,接着又回到子线程循环10次,接着再回到主线程又循环100,如此循环50次,请写出程序。 38 57、介绍Collection框架的结构 43 58、Collection框架中实现比较要实现什么接口 ...

    java面试宝典2012

    56、子线程循环10次,接着主线程循环100,接着又回到子线程循环10次,接着再回到主线程又循环100,如此循环50次,请写出程序。 42 57、介绍Collection框架的结构 47 58、Collection框架中实现比较要实现什么接口 47 ...

    Java面试宝典2012新版

    56、子线程循环10次,接着主线程循环100,接着又回到子线程循环10次,接着再回到主线程又循环100,如此循环50次,请写出程序。 38 57、介绍Collection框架的结构 43 58、Collection框架中实现比较要实现什么接口 43...

    Java 面试宝典

    Overloaded 的方法是否可以改变返回值的类型? ......................................................................................................................................... 14 19、构造器 ...

Global site tag (gtag.js) - Google Analytics