zoukankan      html  css  js  c++  java
  • java多线程技术之(callable和future)

            接着上一篇继续并发包的学习,本篇说明的是Callable和Future,它俩很有意思的,一个产生结果,一个拿到结果。

            Callable接口类似于Runnable,从名字就可以看出来了,但是Runnable不会返回结果,并且无法抛出返回结果的异常,而Callable功能更强大一些,被线程执行后,可以返回值,这个返回值可以被Future拿到,也就是说,Future可以拿到异步执行任务的返回值,下面来看一个简单的例子:

     1 public class CallableAndFuture {
     2     public static void main(String[] args) {
     3         Callable<Integer> callable = new Callable<Integer>() {
     4             public Integer call() throws Exception {
     5                 return new Random().nextInt(100);
     6             }
     7         };
     8         FutureTask<Integer> future = new FutureTask<Integer>(callable);
     9         new Thread(future).start();
    10         try {
    11             Thread.sleep(5000);// 可能做一些事情
    12             System.out.println(future.get());
    13         } catch (InterruptedException e) {
    14             e.printStackTrace();
    15         } catch (ExecutionException e) {
    16             e.printStackTrace();
    17         }
    18     }
    19 }

            FutureTask实现了两个接口,Runnable和Future,所以它既可以作为Runnable被线程执行,又可以作为Future得到Callable的返回值,那么这个组合的使用有什么好处呢?假设有一个很耗时的返回值需要计算,并且这个返回值不是立刻需要的话,那么就可以使用这个组合,用另一个线程去计算返回值,而当前线程在使用这个返回值之前可以做其它的操作,等到需要这个返回值时,再通过Future得到,岂不美哉!这里有一个Future模式的介绍:http://openhome.cc/Gossip/DesignPattern/FuturePattern.htm

            下面来看另一种方式使用Callable和Future,通过ExecutorService的submit方法执行Callable,并返回Future,代码如下:

     1 public class CallableAndFuture {
     2     public static void main(String[] args) {
     3         ExecutorService threadPool = Executors.newSingleThreadExecutor();
     4         Future<Integer> future = threadPool.submit(new Callable<Integer>() {
     5             public Integer call() throws Exception {
     6                 return new Random().nextInt(100);
     7             }
     8         });
     9         try {
    10             Thread.sleep(5000);// 可能做一些事情
    11             System.out.println(future.get());
    12         } catch (InterruptedException e) {
    13             e.printStackTrace();
    14         } catch (ExecutionException e) {
    15             e.printStackTrace();
    16         }
    17     }
    18 }
     

            代码是不是简化了很多,ExecutorService继承自Executor,它的目的是为我们管理Thread对象,从而简化并发编程,Executor使我们无需显示的去管理线程的生命周期,是JDK 5之后启动任务的首选方式。

            执行多个带返回值的任务,并取得多个返回值

    public class CallableAndFuture {
    	public static void main(String[] args) {
    		ExecutorService threadPool = Executors.newCachedThreadPool();
    		CompletionService<Integer> cs = new ExecutorCompletionService<Integer>(threadPool);
    		for(int i = 1; i < 5; i++) {
    			final int taskID = i;
    			cs.submit(new Callable<Integer>() {
    				public Integer call() throws Exception {
    					return taskID;
    				}
    			});
    		}
    		// 可能做一些事情
    		for(int i = 1; i < 5; i++) {
    			try {
    				System.out.println(cs.take().get());
    			} catch (InterruptedException e) {
    				e.printStackTrace();
    			} catch (ExecutionException e) {
    				e.printStackTrace();
    			}
    		}
    	}
    }      
    

      

            其实也可以不使用CompletionService,可以先创建一个装Future类型的集合,用Executor提交的任务返回值添加到集合中,最后遍历集合取出数据,代码略。        

            本文来自:高爽|Coder,原文地址:http://blog.csdn.net/ghsau/article/details/7451464,转载请注明。

  • 相关阅读:
    Account group in ERP and its mapping relationship with CRM partner group
    错误消息Number not in interval XXX when downloading
    错误消息Form of address 0001 not designated for organization
    Algorithm类介绍(core)
    梯度下降与随机梯度下降
    反思
    绘图: matplotlib核心剖析
    ORB
    SIFT
    Harris角点
  • 原文地址:https://www.cnblogs.com/lintong/p/4373120.html
Copyright © 2011-2022 走看看