精华内容
下载资源
问答
  • 实现线程返回值收集 最近有一个需求,需要查询大量数据并进行分析,最后对结果进行处理。由于数据量比较大,故采用多线程来进行数据的查询和处理,但是在最后对结果进行收集时出现了问题。开始采用Runnable接口来...

    实现多线程返回值收集

    最近有一个需求,需要查询大量数据并进行分析,最后对结果进行处理。由于数据量比较大,故采用多线程来进行数据的查询和处理,但是在最后对结果进行收集时出现了问题。开始采用Runnable接口来实现多线程,但是此方法不支持返回值无法获取到结果,后来通过参数传递进集合来进行收集,此时会发现子程序还未完成主程序已经执行完,集合此时为空,收集结果失败。
    经过查询资料,发现java多线程有一个Callable接口,此接口支持返回值,解决了不能收集多线程执行结果的问题。具体操作如下(并非完整代码)。

    1.实现Callable接口

    public class ExportAccForecast implements Callable<List<Map>>{
    	
    }
    

    Callable<List>返回值的类型可以根据自己的需求修改。

    2. ExecutorService调用开启线程

    public static ExecutorService executorService;
    executorService = new ThreadPoolExecutor(CPUNum * threadNumPerCPU*2, CPUNum * threadNumPerCPU*2, 0L,
    				TimeUnit.MILLISECONDS, workQueue,
    				new CBSSOrderThreadFactory());
    				
    for (TRegion region : provinceRegionList) {
         Future<List<Map>> future = CBSSOrderProcessor.executorService.submit(new ExportAccForecast(region));
         List<Map> maps = future.get();
         dataList.addAll(maps);               
    }
              
    

    future.get()会获取到线程返回的结果,如果线程未结束,主线程会在此处等待子线程完成,返回结果。

    展开全文
  • 如何实现处理线程返回值 有时,程序的运行依赖子任务的返回值。当子任务交给子线程去完成的时候,需要获取他们的返回值,这就要考虑如何获取子线程的返回值。有三种解决方式 1.主线程等待法。 主线程循环等待,...

    如何给run()方法传参

    • 构造函数传参
    • 成员变量传参
    • 回调函数传参

    如何实现处理线程的返回值

    有时,程序的运行依赖子任务的返回值。当子任务交给子线程去完成的时候,需要获取他们的返回值,这就要考虑如何获取子线程的返回值。有三种解决方式

    1.主线程等待法。

    主线程循环等待,直到目标子线程返回值为止

    public class CycleWait implements Runnable {
        private String value;
        @Override
        public void run() {
            try {
                Thread.sleep(5000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            value = "we have data now";
        }
    
        public static void main(String[] args) {
            CycleWait cw = new CycleWait();
            Thread thread = new Thread(cw);
            thread.start();
            System.out.println("value: "+cw.value);
        }
    }
    

    运行结果

    value: null
    

    main线程并没有等到子线程给value赋值就往下执行了,没有获取到value的值,接下来代码改造

    public class CycleWait implements Runnable {
        private String value;
        @Override
        public void run() {
            try {
                Thread.sleep(5000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            value = "we have data now";
        }
    
        public static void main(String[] args) throws InterruptedException {
            CycleWait cw = new CycleWait();
            Thread thread = new Thread(cw);
            thread.start();
            while (cw.value == null){
                Thread.sleep(100);
            }
            System.out.println("value: "+cw.value);
        }
    }
    

    打印结果

    value: we have data now
    

    通过判断cw的value值是否为null,如果为null,就一直将主线程休眠,知道子线程返回值。这就是主线程等待法。
    优点
    实现简单
    缺点

    • 需要自己实现循环等待的逻辑。当等待的变量增加,while中要判断的变量会增加,会非常臃肿。
    • 等待的时间不确定,无法精准控制。比如等待中的100毫秒内有值,也无法将程序直接向下进行

    使用Thread类的join()方法阻塞当前线程以等待子线程处理完毕

    public class CycleWait implements Runnable {
        private String value;
        @Override
        public void run() {
            try {
                Thread.sleep(5000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            value = "we have data now";
        }
    
        public static void main(String[] args) throws InterruptedException {
            CycleWait cw = new CycleWait();
            Thread thread = new Thread(cw);
            thread.start();
    //        while (cw.value == null){
    //            Thread.sleep(100);
    //        }
            thread.join();
            System.out.println("value: "+cw.value);
        }
    }
    

    打印结果

    value: we have data now
    

    优点
    实现简单,控制精准
    缺点
    粒度不够细。当主线程创建多个子线程时,判断某个线程返回值为某个值是,让另外子线程去run,这种更精准的依赖关系,join无法做到。

    通过Callable接口实现:通过FutureTask Or 线程池获取

    jdk5之前,线程是没有返回值的,想要获取返回值要大费周折

    FutureTask

    public class MyCallable implements Callable<String> {
        @Override
        public String call() throws Exception {
            String value = "test";
            System.out.println("ready to work");
            Thread.sleep(5000);
            System.out.println("task done");
            return  value;
        }
    }
    
    public class FutureTaskDemo {
        public static void main(String[] args) throws ExecutionException, InterruptedException {
            FutureTask<String> task = new FutureTask<>(new MyCallable());
            new Thread(task).start();
            if (!task.isDone()){
                System.out.println("not finish");
            }
            System.out.println("task return:" +task.get());
        }
    }
    

    运行结果

    not finish
    ready to work
    task done
    task return:test
    

    FutureTask中有isDone()方法判断FutureTask构造方法传入的Callable实现类是否执行完成。FutureTaskget()方法会阻塞当前线程,直到FutureTask构造方法传入的Callable实现类的call()方法执行完毕,最后return返回值

    线程池

    public class ThreadPoolDemo {
        public static void main(String[] args) {
            ExecutorService executorService = Executors.newCachedThreadPool();
            Future<String> future = executorService.submit(new MyCallable());
            if (!future.isDone()){
                System.out.println("not finish");
            }
            try {
                System.out.println(future.get());
            } catch (InterruptedException | ExecutionException e) {
                e.printStackTrace();
            } finally {
                executorService.shutdown();
            }
        }
    }
    

    打印结果

    not finish
    ready to work
    task done
    test
    

    使用线程池,可以提交多个实现Callable的类,去让线程池并发的去处理结果。方便对实现Callable的类统一管理。

    展开全文
  • 2. 如何实现处理线程返回值 2.1 主线程等待法 主线程等待法实现起来比较简单,但是必须自己实现线程等待逻辑,当需要等待的变量一多,代码会变得异常的臃肿,而且无法控制等待多久,无法精准控制 2.2 使用Thread...

    1. 给run()方法传参

    实现的方式主要有三种

    1. 构造函数传参
    2. 成员变量传参(set)
    3. 回调函数传参

    这里不贴具体代码。可以自行实验

    2. 如何实现处理线程的返回值

    2.1 主线程等待法

    主线程等待法实现起来比较简单,但是必须自己实现线程等待逻辑,当需要等待的变量一多,代码会变得异常的臃肿,而且无法控制等待多久,无法精准控制
    在这里插入图片描述
    在这里插入图片描述

    2.2 使用Thread类的join()阻塞当前线程以等待子线程处理完毕

    使用join也能得到同样的结果,并且不用线程去做等待,join方法能做到比主线程等待法做到更精准的控制,实现起来更简单,但是缺点是粒度不够细,比如run方法里有循环任务,当i=5的时候需要执行别的线程任务时,无法使用join方法来控制
    在这里插入图片描述
    在这里插入图片描述

    2.3 通过Callable接口实现: 通过FutureTask 或者通过线程池获取

    2.3.1 通过Future Task获取

    1. 创建自定义类,实现Callable接口
    2. 重写call方法,并将业务逻辑写在call方法中
    3. 创建自定义类对象
    4. 创建FutureTask对象,并将callable对象传入
    5. 创建Thread对象,传入FutureTask对象,由于FutureTask类实现了RunnableFuture接口,RunnableFuture接口继承了Runnable接口,所以可以传入Thread对象中
    6. 启动线程执行任务
    7. 调用isDone方法判断任务是否执行完成
    8. 调用get()方法获取线程任务返回值
      在这里插入图片描述
      在这里插入图片描述

    2.3.2 通过线程池获取返回值

    1. 创建线程池
    2. 往线程池提交MyCallable执行线程
    3. 使用isDone函数判断任务是否执行完成
    4. 获取线程返回值
    5. 关闭线程池
      在这里插入图片描述
    展开全文
  • Thread 处理线程返回值

    2020-03-18 11:34:06
    方法二: 使用Thread类的join()阻塞当前线程以等待当前线程处理完毕。缺点:处理细读不够。 方法三: 使用Callable接口实现; 通过FutureTask Or 线程池Executors.newCachedThreadPool()获取。使用线程池优势:可以...

    方法一: 主线程等待法 缺点,等待时间不精准,以设定的等待时间为一个单位,如果返回的变量比较多,则while条件繁琐。

    方法二: 使用Thread类的join()阻塞当前线程以等待当前线程处理完毕。缺点:处理细读不够。

    方法三: 使用Callable接口实现; 通过FutureTask Or 线程池Executors.newCachedThreadPool()获取。使用线程池优势:可以提交多个实现callable方法的类,让线程池并发的处理结果。方便线程池对这些callable方法的类做统一的管理。

     

    package com.mall.controllor.alene;
    
    /**
     * Created by 60341 on 2020/3/17.
     */
    public class CycleWait implements Runnable{
        private String value;
        @Override
        public void run() {
            try {
                Thread.currentThread().sleep(5000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            value = " have data now! ";
        }
    
        public static void main(String[] args) throws InterruptedException {
            CycleWait cycleWait = new CycleWait();
            Thread t = new Thread(cycleWait);
            t.start();
            //方法一;主线程等待法 缺点,等待时间不精准,以设定的等待时间为一个单位,如果返回的变量比较多,则while条件繁琐。
            while(cycleWait.value ==null){
                Thread.currentThread().sleep(100);
            }
            //使用Thread类的join()阻塞当前线程以等待当前线程处理完毕。缺点:处理细读不够,
            t.join();
            //使用Callable接口实现;通过FutureTask Or 线程池获取
    
            System.out.println(cycleWait.value);
        }
    }
    
    package com.mall.controllor.alene;
    
    import java.util.concurrent.Callable;
    
    /**
     * Created by 60341 on 2020/3/18.
     */
    public class MyCallable implements Callable<String> {
        @Override
        public String call() throws Exception {
            String value = "test";
            System.out.println("Ready to work ");
            Thread.currentThread().sleep(5000);
            System.out.println(" task is done ");
            return value;
        }
    }
    package com.mall.controllor.alene;
    
    import java.util.concurrent.ExecutionException;
    import java.util.concurrent.FutureTask;
    
    /**
     * Created by 60341 on 2020/3/18.
     */
    public class FutureTaskDemo {
    
        public static void main(String[] args) throws ExecutionException, InterruptedException {
            //FutureTask<String> ,实现了RunnableFuture接口,该接口继承了Runnable,所以可以理用Thread实现多线程;
            // FutureTask<String>构造函数中,可以接受Callable的实现实例。
            // FutureTask<String>中String为ew MyCallable()的call方法返回值类型;
            FutureTask<String> futureTask  = new FutureTask<String>(new MyCallable());
            //开启线程,Thread可以接受runnable实现。
            new Thread(futureTask).start();
            //futureTask.isDone()表示Callable的实现实例的call方法已经执行完毕,并返回数据。
            if(!futureTask.isDone()){
                System.out.println("task has not finished,please wait");
            }
            //futureTask.get() 得到Callable的实现实例的call方法返回的数据后才进行下一步处理。
            // futureTask.get(long timeout, TimeUnit unit)是返回超时抛异常
            System.out.println("task return: " + futureTask.get() );
        }
    }
    
    package com.mall.controllor.alene;
    
    import java.util.concurrent.ExecutionException;
    import java.util.concurrent.ExecutorService;
    import java.util.concurrent.Executors;
    import java.util.concurrent.Future;
    
    /**
     * Created by 60341 on 2020/3/18.
     */
    public class ThreadPoolDemo {
        //使用线程池优势:可以提交多个实现callable方法的类,让线程池并发的处理结果。方便线程池对这些callable方法的类做统一的管理。
        public static void main(String[] args){
            //创建线程池
            ExecutorService newCachedThreadPool = Executors.newCachedThreadPool();
            //把线程任务提交到线程池中
            Future<String> future = newCachedThreadPool.submit(new MyCallable());
            //线程是否执行完,并返回结果
            if (!future.isDone()){
                System.out.println("task has not finished,please wait");
            }
            //等待,直到返回线程结果
            try {
                System.out.println(future.get());xia
            } catch (InterruptedException e) {
                e.printStackTrace();
            } catch (ExecutionException e) {
                e.printStackTrace();
            } finally {
                //关闭线程池
                newCachedThreadPool.isShutdown();
            }
        }
    }
    

     

    展开全文
  • 了解了如何在run方法内进行传参之后,那么要如何实现处理线程返回值呢? 实现处理线程返回值一共有三种方法: 1、主线程等待法 使主线程循环等待知道目标子线程返回值为止; 下面是一个简单的demo: 使用主线程...
  • 线程执行过程中可能会存在一...方式2:使用Thread类的join()阻塞当前线程以等待子线程处理完毕 join方法 作用:让调用该方法的线程在执行完run()方法后,再执行join方法后面的代码。将两个线程合并,用于实现同步功
  • 如何实现处理线程返回值? 关于线程的返回值,就是一个痛点了。因为我们有的程序的执行,是依赖于子任务的返回值进行的,当子任务交由子线程去执行的时候,是需要获取到它们的返回值的,这个时候怎么办?即实现子...
  • 如何实现处理线程返回值? 一、主线程等待法。缺点,需要自己实现等待的逻辑,等待的变量如果过多,逻辑就会多,代码就是非臃肿,循环多久是不确定的。没法精准的控制。 二、使用Thread 类的join() 阻塞当前线程...
  • python中的多线程设置方法以及获得子线程返回值的几种方式。
  • 使用Thread类的join()阻塞当前线程以等待子线程处理完毕 通过Callable接口实现:通过FutureTask Or 线程池来获取 // 方法一 while (cycleWait.value == null) { Thread.currentThread().sleep(200); }  ...
  • 有三种实现方式: 主线程等待法; 使用Thread类的join方法阻塞当前线程以等待子线程处理完毕; 通过Callable接口实现,通过FutureTask 或者线程池; ...
  • 这篇文章主要记录一下有返回值的多线程该怎么实现。 之前的文章有提到过ThreadPoolTaskExecutor线程池执行任务有几个方法: executor.execute(Runnable task):完美适用于没有返回值的情况。未捕获的异常会抛出 ...
  • Java 多线程 返回值

    千次阅读 2020-03-21 14:50:18
    该案例主要是结合多线程、ThreadPoolExecutor线程池实现的一个有返回值的多线程功能。 二)第一个线程类 创建一个ListThread线程类,继承java.util.concurrent.Callable接口,并指定方法具体的返回值类型。 ...
  • 如何给run方法传参? (1)构造函数传参 ...如何实现处理线程返回值? (1)主线程等待法 public class CycleWait implements Runnable{ private String value; @Override public void run() { try{ ...
  • java获取多线程返回值

    千次阅读 2019-10-30 08:44:43
    对于多线程大家都不陌生,可以提高咱们程序的执行效率,但是各线程之间都是独立运行,如何来获取各个线程的数据并集中处理呢?废话少说,下面上代码。 1.首先多线程实现Callable接口,记住是Callable,一定要加上...
  • 线程返回值的例子

    千次阅读 2018-09-03 14:15:21
    当我们面临大量数据查询的时候,...目前的处理方式是用多线程实现。   那么,问题来了,多线程的查询,关键问题在于,传递了参数,如何将查询出的结果返回。   解决方案是采用Callable:   一、一个简单的d...
  • 线程处理返回值

    2019-09-08 14:43:08
    大家都知道new一个线程或者实现Ruannable接口,调度这些线程是没有返回值的,如果我们需要线程任务处理完毕会返回一个成功与否的标志,那么可以采用下面的方式 public class Task implements Callable<String> ...
  • Android平台调用Web Service:线程返回值

    千次阅读 热门讨论 2014-05-21 10:28:09
    对于Java多线程的理解,我以前仅仅局限于实现Runnable接口或者继承Thread类,然后重写run()方法,最后start()调用就算完事,但是一旦涉及死锁以及对共享资源的访问和随时监控线程的状态和执行顺序和线程返回值等就...
  • 我们知道,run方法是一个Thread内部类的重写方法,没有参数的导入,也没有返回值的设定。但我们若是想要实现在run方法内进行传参,一共有三种方法: 构造函数传参 成员变量传参 回调函数传参 ...
  • 最近遇到一个问题:有一大堆的债券,需要...最终决定使用callable+future来实现: 具体代码如下: @RequestMapping("/test") public Object test(HttpServletRequest request){ try{ //创建一个线程池 Executo
  • 但是呢,这两个数据要生成到一个文件内,且要求有先后顺序,请问多线程返回值应该怎么处理,最好给个具体的代码实现,多谢各位。 ps: 楼下的大哥们可以拿这个举例子 我有两个方法 int func1 (int x,int y...
  • java创建线程有2种方式,一种是集成Thread类,一种是实现runnable接口。这两种方法在执行线程过后都无法获取执行出来的结果。如果想获取结果就必须通过共享变量或线程间的通讯的方式。 自jdk1.5之后,提供了Future...
  • 线程中,一般主线程创建线程(CreateThread)后,由工作线程函数完成具体内容,工作线程在返回时通过发消息PostMessage告诉主线程结果,主线程做相当处理。 项目需求: 总共有多条任务要执行,主线程需要需要...
  • 如何获取线程返回值

    千次阅读 2020-06-22 17:50:12
    获取线程的返回值 ...通过Callable接口实现call()获取线程返回值(通过FutrueTask Or 线程池获取,推荐使用) FutrueTask的构造方法可以传入Callable实现类的实例; isDone()可以判断call是否执行结束;
  • /** * @author chenzhen * Created by chenzhen on 2018/8/22. */ @Data public class QuickPullGit implements Callable> { private static Logger logger = LoggerFactory.... //拼接线程返回值 for(int i =0;i
  • 前言 经常会遇到一些性能问题,比如调用某个接口,可能要循环调用100...多线程常规的有两种实现方式,即继承Tread类,实现Runnable接口,但是这两种实现方式,有一个共同的问题,就是没有返回值,对于我们来说,获...
  • 有时候,我们要用线程来异步的处理某些耗时的任务,或者关联性不大的任务,并且希望得到这个线程的执行的结果,也就是有个返回值告诉我们任务执行的怎么样 java提供一个有返回值线程实现这种需求. Callable  1...
  • 通过几个实验练习,学习线程之间连接的具体实现。下面列举了两个例子,一个是子线程返回简单数据类型;另一个是子线程返回复杂数据类型。 实现代码 子线程返回复杂数据类型 #include #include #include #include ...
  • 在threading中,并没有实现返回值的方法,我们可以用数据库或者是全局变量来实现返回值的获取。这里使用的是全局变量。 def thread_function(age): for i in age: i += 1 q.put( { 'age': i ...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 229,769
精华内容 91,907
关键字:

如何实现处理线程的返回值