`

处理 子线程的返回值

 
阅读更多
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();
  }
}
分享到:
评论

相关推荐

    python从子线程中获得返回值的方法

    - **子线程**:在主程序运行时创建的新线程,可以用来执行一些独立的任务,如网络请求、文件读写等操作,从而提高程序的响应速度和效率。 #### 知识点二:Python中创建线程的方式 在Python中,可以通过`threading`...

    Java多线程--让主线程等待所有子线程执行完毕在执行

    6. 在主线程中,启动所有子线程后,使用一个循环不断检查`ImportThread.hasThreadRunning()`,直到返回值为`false`,表示所有子线程都已经完成。 这样,主线程会在所有子线程运行结束后才继续执行,而子线程则可以...

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

    本文将详细探讨如何在多线程环境中确保所有子线程执行完毕后,主程序再进行后续操作,并且如何获取子线程的返回结果。这涉及到线程的同步与通信,是理解并发编程的关键点。 首先,多线程执行时,主线程会创建并启动...

    C#多线程函数如何传参数和返回值[归类].pdf

    但是,微软提供了Invoke 的方法,其作用就是让子线程告诉窗体线程来完成相应的控件操作。 例如,可以使用Invoke 方法来更新界面上的控件。例如,定义一个委托public delegate void MyInvoke(string str); 定义一个...

    C#,winform,ShowDialog,子窗体向父窗体传值

    在C# WinForms应用开发中,子窗体与父窗体之间的数据传递是一个常见的需求,尤其是在需要用户输入或选择特定信息的场景下。...通过适当的错误处理和验证逻辑,可以进一步提升用户体验,确保数据的完整性和有效性。

    fork()编程fork()编程fork()编程

    `fork()`可能会因系统资源不足(如内存不足)而失败,此时需要检查返回值并适当地处理错误。 五、进程同步与等待 在多进程环境中,通常需要父进程等待子进程结束,这可以通过`wait()`或`waitpid()`函数实现。父...

    快速解决pyqt5窗体关闭后子线程不同时退出的问题

    而子线程通常用于执行非GUI任务,如数据处理或网络通信。默认情况下,当主线程(即包含`QApplication`的线程)退出时,所有关联的子线程也将被终止。但是,如果子线程中存在无限循环,且没有正确的退出机制,那么...

    Python多线程获取返回值代码实例

    需要注意的是,使用`join()`方法是必要的,因为它确保主线程等待所有子线程结束,防止在结果未准备好时尝试获取结果。如果不使用`join()`,调用`get_result()`可能会因为线程还在执行而引发异常。 总结起来,Python...

    python获取多线程及子线程的返回值

    总结来说,Python中获取多线程和子线程返回值主要有两种方式:一是自定义线程类,将结果存储在实例属性中;二是使用`Queue`对象进行线程间的通信,将结果存入队列,由主线程取出。无论哪种方式,都需要确保主线程...

    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_启动...

    Linux系统编程-(pthread)线程创建与使用.zip

    - 主线程调用`pthread_exit`时,所有非分离的子线程也将结束,除非它们已经设置为分离状态。 4. **线程安全与信号处理** - 当多线程进程捕获到信号,只会影响主线程,不影响其他子线程的执行。线程间信号处理需要...

    os multithread sorting

    主线程将大任务分解为多个小任务,然后分配给子线程进行排序。子线程完成后再由主线程合并结果。 4. **负载均衡**:为了最大化效率,线程间的任务分配应尽可能均匀。如果某个线程的任务过重,可能导致其他线程空闲...

    perl中的线程.docx

    一旦`join`,子线程的资源会被释放,其返回值(如果有)可以被主线程获取。 Perl线程的状态包括:创建(create)、运行(running)、执行完毕(finished execution)、joinable、已join(joined)或未分离...

    操作系统linux编程答案

    主线程(父线程)在所有子线程创建完毕后,等待所有子线程执行完毕,然后输出`globalnum`的最终值。 ### 文件操作与信号处理 #### 示例3:文件操作与信号处理(部分代码缺失) 尽管这部分代码未完全展示,但可以...

    如何使用读写线程实现串口通信

    接着,我们要构建一个主线程和两个子线程——读线程和写线程。主线程主要负责初始化串口、创建读写线程并管理整个通信过程。读线程则持续监控串口,一旦有数据到来,就调用`ReadFile`读取并处理数据。写线程则接收...

    日常记录学习,基础知识,学习笔记

    在多线程服务器中,如Web服务器,主线程通常不希望因等待子线程结束而被阻塞,这时可以在子线程启动时或运行中调用`pthread_detach(pthread_self())`。而`pthread_join()`则常用于需要获取子线程返回值或确保子线程...

    VC6.0 MFC多线程的例子

    在MFC中,主线程通常负责处理用户界面,而子线程执行计算任务。为了避免界面假死,子线程不应直接修改UI元素,而应使用`PostMessage()`或`AfxGetMainWnd()-&gt;PostMessage()`发送消息给主线程,由主线程来更新UI。这样...

    C#在子线程中更新窗口部件的写法

    这在处理大量数据或需要立即返回结果的情况下很有用,但需要注意的是,`BeginInvoke`可能会导致UI更新的顺序与子线程执行的顺序不同步。 总的来说,要安全地在C#的子线程中更新窗口部件,你需要使用`Invoke`或`...

Global site tag (gtag.js) - Google Analytics