java语言 多线程 Callable接口的使用(二)

在前面一篇文章中,我们简单介绍了java语言中,如何创建线程,使用线程,其中也提到了 Callable的使用,这里单独介绍下 Callable这个接口

看看他的定义:
@FunctionalInterface
public interface Callable<V> {
    /**
     * Computes a result, or throws an exception if unable to do so.
     *
     * @return computed result
     * @throws Exception if unable to compute a result
     */
    V call() throws Exception;
}

和Runnable接口类似,也是一个函数式接口,这样我们可以通过lambda表达式进行使用。

Callable接口的特点:提供了方法返回值,这样在线程执行完后,可以获取到相应的返回值。

我们先看看怎么使用:一是可以作为FutureTask的参数,传入到FutureTask对象中,作为任务执行。二是依赖线程池Executor,作为task丢入到线程池中作为独立任务执行。

Talk is cheap,show me your code!!

public class CallableDemo {

   static ExecutorService executorService = Executors.newSingleThreadExecutor();

    public static void main(String[] args) throws Exception {
        callableDemo();
    }

    private static void callableDemo() throws Exception {
        Callable<Long> callable = new Callable<Long>() {
            @Override
            public Long call() throws Exception {
                MyLog.printTimeAndThread("callable");
                Thread.sleep(2500);
                return 100L; //Thread.currentThread().getId();
            }
        };

        // 1. Callable 对象作为FutureTask对象的参数,在FutureTask中中执行
        FutureTask<Long> futureTask = new FutureTask<Long>(callable);
        Thread thread = new Thread(futureTask);
        thread.start();
        Long result = futureTask.get();
        System.out.println("futureTask callable result: " + result);

        System.out.println("===========================");

        // 2. Callable 对象丢入到Executor 线程池中执行
        Future<Long> future = executorService.submit(callable);
        Long result2 = future.get();
        System.out.println("executorService callable result: " + result2);

        executorService.shutdown();
    }

}



public class MyLog {

    public static void sleepMillis(long millis) {
        try {
            Thread.sleep(millis);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    public static void printTimeAndThread(String tag) {
        String result = new StringJoiner("\t|\t")
                .add(String.valueOf(System.currentTimeMillis()))
                .add(String.valueOf(Thread.currentThread().getId()))
                .add(Thread.currentThread().getName())
                .add(tag)
                .toString();
        System.out.println(result);
    }
}

运行结果:
1619072927241	|	12	|	Thread-0	|	callable
futureTask callable result: 100
===========================
1619072929742	|	13	|	pool-1-thread-1	|	callable
executorService callable result: 100


这个结果很好理解,我相信,就不多解释了。

 

把上面的代码这样改下:

 private static void callableDemo() throws Exception {
        Callable<Long> callable = new Callable<Long>() {
            @Override
            public Long call() throws Exception {
                MyLog.printTimeAndThread("callable");
                Thread.sleep(2500);
                return 100L; //Thread.currentThread().getId();
            }
        };

        // 1. Callable 对象作为FutureTask对象的参数,在FutureTask中中执行
        FutureTask<Long> futureTask = new FutureTask<Long>(callable);
        Thread thread = new Thread(futureTask);
        thread.start();
        Long result = futureTask.get();
        System.out.println("futureTask callable result: " + result);

        System.out.println("===========================");

        // 2. Callable 对象丢入到Executor 线程池中执行
        Future<Long> future = executorService.submit(callable);
        Long result2 = future.get();

        Long result3 = callable.call();                // 多加了这2行代码
        System.out.println("result3: " + result3);     // 多加了这2行代码

        System.out.println("executorService callable result: " + result2);

        executorService.shutdown();
    }

执行的结果:
1619073040316	|	12	|	Thread-0	|	callable
futureTask callable result: 100
===========================
1619073042818	|	13	|	pool-1-thread-1	|	callable
1619073045318	|	1	|	main	|	callable
result3: 100
executorService callable result: 100


可以看出 callable对象执行了两次,相当于这个任务重复执行了两次,一次是在executor线程池中执行的,一次是在main线程执行的。


 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值