Callable实现多线程

方式一:通过线程池的方式

和Thread,Runnable实现多线程的区别

  • Callable使用 call()方法, Runnable和Thread使用 run() 方法。
  • call() 可以返回值, 而 run()方法不能返回。
  • call() 可以抛出受检查的异常,比如ClassNotFoundException, 而run()不能抛出受检查的异常。

示例

import java.util.concurrent.*;

public class CallableExample01 implements Callable<Boolean> {

    //执行体
    public Boolean call() throws Exception {
        System.out.println("执行的线程为:" + Thread.currentThread().getName());
        return true;
    }

    public static void main(String[] args) throws ExecutionException, InterruptedException {
        CallableExample01 c1 = new CallableExample01();
        CallableExample01 c2 = new CallableExample01();
        CallableExample01 c3 = new CallableExample01();
        //1 创建执行服务
        ExecutorService ser = Executors.newFixedThreadPool(3);
        //2 提交执行
        Future<Boolean> f1 = ser.submit(c1);
        Future<Boolean> f2 = ser.submit(c2);
        Future<Boolean> f3 = ser.submit(c3);
        //3 获取结果
        boolean res = f1.get();
        boolean res1 = f2.get();
        boolean res2 = f3.get();
        //4 关闭服务
        ser.shutdownNow();
    }

执行结果

执行的线程为:pool-1-thread-1
执行的线程为:pool-1-thread-2
执行的线程为:pool-1-thread-3

方式二:使用FutureTask

  • Callble实现的多线程是没法直接通过Thread.start()的方式调用的,而是通过Runnable接口间接与Thread取得联系。

  • 在Runnable实现类中有一个名为FutureTask的子类,在FutureTask类中有如下一个构造方法,该构造方法将Callable与Runnable联系起来。之后我们就可以通过Thread来间接执行Callable了。

    FutureTask(Callable<V> callable) 
    //创建一个 FutureTask ,它将在运行时执行给定的 Callable 。 
    

示例

public class CallableExample {
    public static void main(String[] args) {
        MyThread myThread = new MyThread();
        FutureTask<Integer> futureTask = new FutureTask<>(myThread);
        // 放入Thread中使用,结果会被缓存
        new Thread(futureTask,"A").start();
        new Thread(futureTask,"B").start();

        try {
            //通过get方法可以获取到返回值的结果,但get方法容易产生阻塞
            Integer integer = futureTask.get();
            System.out.println(integer);
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (ExecutionException e) {
            e.printStackTrace();
        }

    }

}
class MyThread implements Callable<Integer> {
    @Override
    public Integer call() throws Exception {
        System.out.println("success in call "+Thread.currentThread().getName());
        return 1024;
    }
}

运行结果如下:

success in call A
1024

结果分析:
我明明start()两个线程A和B,为啥只输出了一个线程的内容呢?
答:这是因为FutureTask的任务仅执行一次,目的是为了提高效率。使用时需要注意这点。

推荐文章:https://blog.csdn.net/qq_44384533/article/details/111920875
参考教程:https://www.kuangstudy.com/

posted @ 2021-04-18 20:50  懒鑫人  阅读(189)  评论(0)    收藏  举报