创建线程的第三种方式——使用Callable接口

Callable是类似于Runnable的接口,实现Callable的类和实现Runnable的类都是可被其他线程执行的任务。

优点:有返回值

缺点:实现繁琐

简单实现:

CallableAndFuture.java
/**
 * 简单实现
 *
 * @author :liuqi
 * @date :2018-06-13 11:10.
 */
public class CallableAndFuture {
    static class MyThread implements Callable<String> {
        @Override
        public String call() throws Exception {
            return "Hello world";
        }
    }

    public static void main(String[] args) {
        ExecutorService threadPool = Executors.newSingleThreadExecutor();
        Future<String> future = threadPool.submit(new MyThread());
        try {
            System.out.println(future.get());
        } catch (Exception e) {

        } finally {
            threadPool.shutdown();
        }
    }
}

运行结果:

Hello world

进阶:

Race.java
/**
 * 实现callable类
 *
 * @author :liuqi
 * @date :2018-06-13 10:13.
 */
public class Race implements Callable<Integer> {
    private String name;
    private long time;
    private boolean flag = true;
    // 步数
    private int step = 0;
    public Race(){
    }
    public Race(String name,int time){
        super();
        this.name = name;
        this.time = time;
    }
    @Override
    public Integer call() throws Exception {
        while(flag){
            Thread.sleep(time);
            step++;
        }
        return step;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public long getTime() {
        return time;
    }

    public void setTime(long time) {
        this.time = time;
    }

    public boolean isFlag() {
        return flag;
    }

    public void setFlag(boolean flag) {
        this.flag = flag;
    }

    public int getStep() {
        return step;
    }

    public void setStep(int step) {
        this.step = step;
    }
}
Demo05.java
/**
 * 使用collable接口创建线程
 *
 * @author :liuqi
 * @date :2018-06-13 10:22.
 */
public class Demo05 {
    public static void main(String[] args) throws InterruptedException,ExecutionException {
        // 创建两个线程
        ExecutorService ser = Executors.newFixedThreadPool(2);
        Race tortoise = new Race("乌龟",1000);
        Race rabbit = new Race("兔子",500);
        // 获取future对象
        Future<Integer> result1 = ser.submit(tortoise);
        Future<Integer> result2 = ser.submit(rabbit);
        // 2秒
        Thread.sleep(2000);
        // 停止线程体循环
        tortoise.setFlag(false);
        rabbit.setFlag(false);
        // 获取值
        int num1 = result1.get();
        int num2 = result2.get();
        System.out.println("乌龟跑了 " + num1 + "步");
        System.out.println("兔子跑了 " + num2 + "步");
        // 停止服务
        ser.shutdownNow();
    }
}

运行结果:

乌龟跑了 3步
兔子跑了 5步

代码地址:https://github.com/yuki9467/TST-javademo/tree/master/src/main/thread

Callable和Runnable有几点不同:

1.Callable规定方法是call(),而Runnable规定方法是run();

2.Callable任务执行后可返回值,而Runnable不能返回值;

3.call()可抛出异常,而run()不能抛出异常;

4.运行Callable任务可拿到一个Future对象,Future表示异步计算的结果,通过Future对象可了解任务执行情况,可取消任务的执行,还可获取任务执行的结果。

猜你喜欢

转载自www.cnblogs.com/yuki67/p/9176909.html