zoukankan      html  css  js  c++  java
  • 6、Callable接口的使用(简单)

    引用学习(狂神说)

    使用解析

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

     

    可以知道以下几点:

    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接口

    那该怎么办?

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

    通过图解拆分关系

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

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

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

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

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

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

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

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

    点开实现类FutureTask

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

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

    具体使用

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

    创建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";
        }
    
    }

    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";
        }
    
    }

    注意点

    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";
        }
    
    }

    致力于记录学习过程中的笔记,希望大家有所帮助(*^▽^*)!
  • 相关阅读:
    Pandas数据存取
    Pandas统计分析
    (4)awk读取行的细节
    (3)awk命令行结构和语法结构
    安装新版gawk
    (2)BEGIN和END语句块
    (1)AWK快速入门
    shell读取文件的几种方式
    Docker 部署 elk + filebeat
    Linux之关于用户的几个重要配置文件
  • 原文地址:https://www.cnblogs.com/zxhbk/p/12955458.html
Copyright © 2011-2022 走看看