引用学习(狂神说)

使用解析

1、首先查看官方文档和源码是如何讲解的

6、Callable接口的使用(简单)

 6、Callable接口的使用(简单)

可以知道以下几点:

1、Callable接口类似于Runnable接口

2、Callable有返回值

3、Callable可以抛出异常

4、调用call()方法

5、Callable支持泛型

2、既然和Runnable接口类似,就直接创建一下

class MyThread implements Callable<String>{

    @Override
    public String call() throws Exception {
        System.out.println("call()");
        return "123";
    }

}

3、重点:如何启动呢?

要知道线程的启动只能通过 new Thread().start()

  • Thread的构造方法中,只能丢入Runnable接口

6、Callable接口的使用(简单)

那该怎么办?

现在知道的是Thread类,和Runnable接口有关系,我们是否可以通过Runnable接口和Thread类挂上关系呢?

通过图解拆分关系

  • 现在你是Callable接口,Runnable接口是的女朋友,Thread类是你女朋友的闺蜜

  • 而现在你想认识你女朋友的闺蜜,怎么办呢?

  • 如果你直接去找你女朋友的闺蜜,肯定会有些突兀或者造成误会!

  • 肯定需要通过你女朋友的介绍,对吧!

  • 那么你的女朋友要如何介绍呢?这是一个问题!

6、Callable接口的使用(简单)

4、查看Runnable接口在文档中的说明

Runnable接口本身没有说明好看的,只是一个函数式接口,里面有个run()方法,仅此而已!

但是它有两个重要的实现类,图中已经标出:

6、Callable接口的使用(简单)

点开实现类FutureTask

往下翻,在构造器中你会发现可以丢入一个Callable接口

6、Callable接口的使用(简单)

 那么现在就可以通过FutureTask实现类和Thread类挂上关系了!

6、Callable接口的使用(简单)

具体使用

有两个坑,需要注意返回参数和缓存

创建Callable线程并启动

package com.zxh.callable;

import java.util.concurrent.Callable;
import java.util.concurrent.FutureTask;

public class CallableTest {
    public static void main(String[] args) {
        MyThread myThread = new MyThread();
        FutureTask futureTask = new FutureTask(myThread);   // 适配器类

        new Thread(futureTask).start();
    }
}
class MyThread implements Callable<String>{

    @Override
    public String call() throws Exception {
        System.out.println("call()");
        return "123";
    }

}

6、Callable接口的使用(简单)

Callable返回的参数和注意点

获取返回的参数

import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;

public class CallableTest {
    public static void main(String[] args) throws ExecutionException, InterruptedException {
        MyThread myThread = new MyThread();
        FutureTask futureTask = new FutureTask(myThread);   // 适配器类

        new Thread(futureTask).start();

        Object o = futureTask.get();
        System.out.println(o);
    }
}
class MyThread implements Callable<String>{

    @Override
    public String call() throws Exception {
        System.out.println("call()");
        return "123";
    }

}

6、Callable接口的使用(简单)

注意点

futureTask.get()方法可能会阻塞

因为call()中可能会存在耗时的任务,所以在获取返回值的时候,就会等待(阻塞)。

一般将get()方法放在最后一行,并用通过异步操作调用。

缓存

  • 当你使用两个线程调用的时候,会发现输出只有1次。

  • 因为结果被缓存,提高了效率

import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;

public class CallableTest {
    public static void main(String[] args) throws ExecutionException, InterruptedException {
        MyThread myThread = new MyThread();
        FutureTask futureTask = new FutureTask(myThread);   // 适配器类

        new Thread(futureTask, "A").start();
        new Thread(futureTask, "B").start();    //结果会被缓存

        Object o = futureTask.get();    // 会阻塞,一般通过异步操作
        System.out.println(o);
    }
}
class MyThread implements Callable<String>{

    @Override
    public String call() throws Exception {
        System.out.println("call()");
        return "123";
    }

}

6、Callable接口的使用(简单)

相关文章:

  • 2021-11-23
  • 2021-08-23
  • 2022-12-23
  • 2021-07-22
  • 2021-11-16
  • 2021-07-04
  • 2022-12-23
  • 2022-12-23
猜你喜欢
  • 2022-02-14
  • 2021-07-05
  • 2022-12-23
  • 2022-12-23
  • 2021-12-10
  • 2021-12-10
  • 2021-08-14
相关资源
相似解决方案