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

    致力于记录学习过程中的笔记,希望大家有所帮助(*^▽^*)!
  • 相关阅读:
    Stuts2的"struts.devMode"设置成true后,不起作用,仍需要重启tomcat
    Javascript和Java获取各种form表单信息的简单实例
    cascade 介绍与用法 ( oracle)
    Struts2拦截器的使用 (详解)
    关于ActionContext.getContext()的用法心得
    mySQL中如何给某一IP段的用户授权?
    【BZOJ4260】Codechef REBXOR (Trie树)
    【BZOJ4500】矩阵(差分约束)
    【BZOJ2054】疯狂的馒头(并查集,线段树)
    【BZOJ1005】[HNOI2008]明明的烦恼(prufer序列)
  • 原文地址:https://www.cnblogs.com/zxhbk/p/12955458.html
Copyright © 2020-2023  润新知