Runnable接口和Callable接口的区别

Runnable接口中的run()方法的返回值是void,它做的事情只是纯粹地去执行run()方法中的代码而已;Callable接口中的call()方法是有返回值的,是一个泛型,和Future、FutureTask配合可以用来获取异步执行的结果。

比如,你想获得一个线程执行过后的一个返回值,那么就可以用Callable+Future/FutureTask却可以获取多线程运行的结果,下面写一个小demo。

public static void main(String[] args) throws ExecutionException, InterruptedException {
    ExecutorService executorService = new ThreadPoolExecutor(10, 10,
            5000L, TimeUnit.SECONDS, new ArrayBlockingQueue<Runnable>(20), new ThreadPoolExecutor.DiscardPolicy());
    List<FutureTask<String>> futureTasks=new ArrayList<>();
    System.out.println("-------------开始---------");
    CountDownLatch countDownLatch = new CountDownLatch(100);
    for (int i=0;i<100;i++){
        Callable<String> callable = new CallableImpl(String.valueOf(i),countDownLatch);
        FutureTask<String> task = new FutureTask<>(callable);
        executorService.submit(task);
        futureTasks.add(task);
        System.out.println(i);
    }
    System.out.println("-------等待定时任务结束-----------"+System.currentTimeMillis());
    countDownLatch.await();
    System.out.println("-------定时任务结束,准备输出-----------"+System.currentTimeMillis());
    futureTasks.forEach(tack->{
        try {
            System.out.println(tack.get());
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (ExecutionException e) {
            e.printStackTrace();
        }
    });
}


static class CallableImpl implements Callable<String> {
    private String str;
    protected CountDownLatch countDownLatch;


    public CallableImpl(String str,CountDownLatch countDownLatch) {
        this.str = str;
        this.countDownLatch=countDownLatch;
    }


    @Override
    public String call() throws Exception {
        //Thread.sleep(1);
        countDownLatch.countDown();
        return this.str + " append some chars and return it";
    }
}

 

posted @ 2021-06-07 21:31  alwaysFly  阅读(192)  评论(0)    收藏  举报