11.Callable接口

Callable 接口类似于 Runnable,两者都是为那些其实例可能被另一个线程执行的类设计的。但是 Runnable 不会返回结果,并且无法抛出经过检查的异常。
特点:
    1.Callable 可以抛出异常
    2.Callable 可以返回结果
    3.Callable 调用get方法时会阻塞
    4.Callable 需要借助FutureTask 去和Thread关联启动
样例:
    public class Juc_Test_Lock {
        public static void main(String[] args) {
            //重点1:创建Callable接口实例
            MyThread myThread=new MyThread();
            //重点2:创建Callable关联的FutureTask
            FutureTask futureTask=new FutureTask(myThread);
            new Thread(futureTask,"线程1").start();
            //重点3:这个方法会阻塞,因为要等待线程执行完毕拿到结果
            Integer result= (Integer) futureTask.get();
            System.out.println("线程返回:"+result);
        }
    }
    //重点4:实现Callable接口
    class MyThread implements Callable<Integer>{
        @Override
        public Integer call() throws Exception {
            System.out.println("call方法");
            return 1024;
        }
    }
    输出:
        call方法
        线程返回:1024
    
问题:如果是两个线程同时启动呢?
    new Thread(futureTask,"线程1").start();
    new Thread(futureTask,"线程2").start();
输出:发现也是调用了一次call方法,理由如下!
    call方法
    线程返回:1024

 FutureTask的构造器如下:会有一个state去标记,如果执行了一次,这个状态会变化!下次就不会执行了
    public FutureTask(Callable<V> callable) {
        if (callable == null)
            throw new NullPointerException();
        this.callable = callable;
        this.state = NEW;       // ensure visibility of callable
    }

 

posted @ 2022-05-19 22:09  努力的达子  阅读(47)  评论(0编辑  收藏  举报