• JAVA 并发编程-返回运行结果(Callable和Future)(九)


       启动一个线程不论使用Thread或者Runnable的时候。都是没有返回结果的。

    也就是说Thread和Runnable的run()方法必须没有返回值。

       public void run(){}

     

    解决方式:

     

    CallableFuture,一个产生结果,一个拿到结果。

     

    简单的来一个实例demo帮助我们理解:


    public class CallableAndFuture {
    
    	/**
    	 * @param args
    	 */
    	public static void main(String[] args) {
    		//单一线程的线程池
    		ExecutorService threadPool =  Executors.newSingleThreadExecutor();
    		Future<String> future =
    			threadPool.submit(
    				new Callable<String>() {
    					public String call() throws Exception {
    						Thread.sleep(2000);
    						return "hello";
    					};
    				}
    		);
    		System.out.println("等待结果");
    		try {
    			System.out.println("拿到结果" + future.get());
    		} catch (InterruptedException e) {
    			e.printStackTrace();
    		} catch (Exception e) {
    			e.printStackTrace();
    		}
    		
    	}
    	
    
    }

    运行结果:

     

    等待结果

    拿到结果hello 

     

    使用场景:

     

    如果有一个非常耗时的返回值须要计算。而且这个返回值不是立马须要的话,那么就能够使用以上这样的方式,用还有一个线程去计算返回值,而当前线程在使用这个返回值之前能够做其他的操作,等到须要这个返回值时,再通过Future得到!

     

    说明:

     

    Future取得的结果类型和Callable返回的结果类型必须一致,这是通过泛型来实现的

    Callable要採用ExecutorServicesubmit方法提交,返回为future对象

     

    CompletionService用于提交一组Callable任务,其take方法返回已完毕的一个Callable任务相应的Future对象

    好比我同一时候种了几块地的麦子,然后就等待收割。收割时,哪块先成熟,则先收割哪块

     

    以下我们来针对CompletionService看一个小demo


    public class CallableAndFuture {
    
    	/**
    	 * @param args
    	 */
    	public static void main(String[] args) {
    		
    		ExecutorService threadPool2 =  Executors.newFixedThreadPool(10);
    		CompletionService<Integer> completionService = new ExecutorCompletionService<Integer>(threadPool2);
    		for(int i=1;i<=10;i++){
    			final int seq = i;
    			completionService.submit(new Callable<Integer>() {
    				@Override
    				public Integer call() throws Exception {
    					Thread.sleep(new Random().nextInt(5000));
    					return seq;
    				}
    			});
    		}
    		for(int i=0;i<10;i++){
    			try {
    				System.out.println(
    						completionService.take().get());
    			} catch (InterruptedException e) {
    				e.printStackTrace();
    			} catch (ExecutionException e) {
    				e.printStackTrace();
    			}
    		}
    	}
    	
    }

    运行结果:

     

    8

    6

    5

    7

    2

    1

    3

    10

    9

    4

     

    总结:

     

          对于多线程运行返回结果这样的需求在实际应用中还是非常少见的,此文仅仅是作为了解学习。




  • 相关阅读:
    企业级开发的权限管理
    asp.net mvc 中的ajax
    拖拽(非原创)
    数据库中主键和外键的设计原则
    第六篇续:动态创建 ListView 模板
    动态创建 ASP.NET Web 服务器控件模板(出自MSDN)
    ASP.NET跨页面传值的几种方法
    奇文共赏 史记货殖列传王石传
    需求该如何分析?
    PopupControlExtender 控件的使用(转)
  • 原文地址:https://www.cnblogs.com/wzzkaifa/p/7141829.html
Copyright © 2020-2023  润新知