多线程之callable学习

最近在看多线程方面的内容,注意到java中原来除了Runnable和Thread以外还有Callable的方式实现多线程,而且Callable还能获得子线程的返回值,这是前面两种方式所不具备的。java

  Callable是一个借口,而且支持泛型,咱们编写多线程只须要实现这个接口,而且重写call方法,要获得Callable的返回值就要使用Future对象,Callable负责计算结果,Future负责拿到结果,具体的使用请看以下两个例子:web

public class CallableAndFuture {
    public static void main(String[] args) {
        Callable<Integer> callable = new Callable<Integer>() {
            public Integer call() throws Exception {
                return new Random().nextInt(100);
            }
        };
        FutureTask<Integer> future = new FutureTask<Integer>(callable);
        new Thread(future).start();
        try {
            Thread.sleep(5000);// 可能作一些事情
            System.out.println(future.get());
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (ExecutionException e) {
            e.printStackTrace();
        }
    }
}

上面例子是经过Thread来包装FutureTask来启动线程,FutureTask实现了两个接口,Runnable和Future,因此它既能够做为Runnable被线程执行,又能够做为Future获得Callable的返回值,那么这个组合的使用有什么好处呢?假设有一个很耗时的返回值须要计算,而且这个返回值不是马上须要的话,那么就能够使用这个组合,用另外一个线程去计算返回值,而当前线程在使用这个返回值以前能够作其它的操做,等到须要这个返回值时,再经过Future获得,岂不美哉!多线程

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

 

public class CallableAndFuture {
    public static void main(String[] args) {
        ExecutorService threadPool = Executors.newSingleThreadExecutor();
        Future<Integer> future = threadPool.submit(new Callable<Integer>() {
            public Integer call() throws Exception {
                return new Random().nextInt(100);
            }
        });
        try {
            Thread.sleep(5000);// 可能作一些事情
            System.out.println(future.get());
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (ExecutionException e) {
            e.printStackTrace();
        }
    }
}

 

  执行多个带返回值的任务,并取得多个返回值,代码以下:spa

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();
            }
        }
    }
}
相关文章
相关标签/搜索