【第五章】JUC之获取多线程方式#Callable接口详解

笔记大纲
  • 获取多线程方式(4种)
  • Runnable&Callable接口区别
  • 如何使用Callable接口
  • FutureTask是什么?(测试代码+结果)

一、获取多线程方式(4种)

  传统的是继承thread类和实现runnable接口;java5后又实现callable接口和在java线程池(常驻堆中的养老区)获得。

二、Runnable&Callable接口区别
class MyTread1 implements Runnable{
    @Override
    public void run() {
        
    }
}
//Callable接口有返回值
class  MyThread2 implements Callable<Integer>{  

    @Override
    public Integer call() throws Exception {
        return null;
    }
}
public class CallableDemo {
    
}
区别runnable接口Callable接口
是否有返回值
是否抛异常
落地方法不一样run()方法call方法
三、如何使用Callable接口
1.查看API,Thread类构造方法无Callable
public class CallableDemo {
    public static void main(String[] args) {
        new Thread(new MyThread1(),"AA").start();//构造方法--Runnable对象
        new Thread(new MyThread2(),"BB").start(); //实现Callable接口的类无法作为构造参数【报错】
    }
}

在这里插入图片描述

2.利用java多态,一个类可以实现多个接口,找“中间人(Runnable-FutureTask)”
public class CallableDemo {
    public static void main(String[] args) {
        new Thread(new MyThread1(),"AA").start();//构造方法--Runnable对象
        //new Thread(new MyThread2(),"BB").start(); //实现Callable接口的类无法作为构造参数【报错】
        FutureTask<Integer> ft = new FutureTask<Integer>(new MyThread2());
		new Thread(ft, "BB").start();
    }
}

java.lang.Runnable接口的实现类FutureTask:

在这里插入图片描述

java.lang.Runnable接口的实现类FutureTask(构造方法)

在这里插入图片描述

java.lang.Runnable接口的实现类FutureTask(get方法)

在这里插入图片描述

java.util.concurrent包中类FutureTask

在这里插入图片描述

四、FutureTask是什么?

  FutureTask表示未来任务,采用异步调用。

  在主线程中需要执行比较耗时的操作时,但又不想阻塞主线程时,可以把这些作业交给Future对象在后台完成,当主线程将来需要时,就可以通过Future对象获得后台作业的计算结果或者执行状态。

  一般FutureTask多用于耗时的计算,主线程可以在完成自己的任务后,再去获取结果(只计算一次,get方法放到最后 )。仅在计算完成时才能检索结果;如果计算尚未完成,则阻塞 get方法。一旦计算完成,就不能再重新开始或取消计算。get方法获取的结果只有在计算完成时获取,否则会一直阻塞直到任务转入完成状态,然后会返回结果或者抛出异常。

  FutureTask单起一个线程,用于计算复杂的任务,与主线程分开,主线程可以专注于业务流程不会被阻塞,前提是在要计算完后去get结果,没有完成就会阻塞。

测试代码1-1:
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;
//Callable接口
class  MyThread implements Callable<Integer>{

    @Override
    public Integer call() throws Exception {
        System.out.println(Thread.currentThread().getName()
            +"======"+"hello,lindaxia");
        return 200;//200表示执行成功
    }
}

public class CallableDemo {
    public static void main(String[] args) throws ExecutionException, InterruptedException {
        FutureTask<Integer> ft = new FutureTask<Integer>(new MyThread());
        new Thread(ft, "ThreadName-AA").start();
        System.out.println(ft.get());
    }
}
打印结果:

在这里插入图片描述

测试代码1-2:

模拟主线程计算尚未完成,则阻塞 get 方法

//Callable接口
class  MyThread implements Callable<Integer>{

    @Override
    public Integer call() throws Exception {
        TimeUnit.SECONDS.sleep(3);//睡眠3秒
        System.out.println(Thread.currentThread().getName()
            +"======"+"hello,lindaxia");
        return 200;//200表示执行成功
    }
}
public class CallableDemo {
    public static void main(String[] args) throws ExecutionException, InterruptedException {
        FutureTask<Integer> ft = new FutureTask<Integer>(new MyThread());
        new Thread(ft, "ThreadName-AA").start();
        System.out.println(ft.get());
        System.out.println("=====主线程名测试======"+Thread.currentThread().getName());

    }
}
打印结果:

期望结果:main线程先输出,最后才去get!现在睡眠3s,才会输出如下!

在这里插入图片描述

测试代码1-3:
public class CallableDemo {
    public static void main(String[] args) throws ExecutionException, InterruptedException {
        FutureTask<Integer> ft = new FutureTask<Integer>(new MyThread());
        new Thread(ft, "ThreadName-AA").start();
        //修改main线程输出外置,在get()之前!!!!
        System.out.println("=====主线程名测试======"+Thread.currentThread().getName());
        System.out.println(ft.get());


    }
}
打印结果:

达到期望结果,主线程先输出,再睡眠3s,接着打印结果!

在这里插入图片描述

测试代码2-1:
public class CallableDemo {
    public static void main(String[] args) throws ExecutionException, InterruptedException {
        FutureTask<Integer> ft= new FutureTask<Integer>(() -> {
            TimeUnit.SECONDS.sleep(3);//睡眠3秒
            System.out.println(Thread.currentThread().getName()
                    + "======" + "hello,lindaxia");
            return 200;//200表示执行成功

        });
        //启动两个线程
        new Thread(ft, "ThreadName-AA").start();
        new Thread(ft, "ThreadName-BB").start();

        System.out.println("=====主线程名测试======"+Thread.currentThread().getName());
        //get()只输出一次,FutureTask只执行一次(ThreadName-AA/BB不确定谁执行)
        System.out.println(ft.get());
        System.out.println(ft.gdayiet());

    }
}
打印结果:

在这里插入图片描述

测试代码2-2

两个实例执行两次(计算两次)!

//Callable接口
class MyThread implements Callable<Integer> {
    @Override
    public Integer call() throws Exception {
        TimeUnit.SECONDS.sleep(3);//睡眠3秒
        System.out.println(Thread.currentThread().getName()
                + "======" + "hello,lindaxia");
        return 200;//200表示执行成功
    }
}

public class CallableDemo {
    public static void main(String[] args) throws ExecutionException, InterruptedException {
        /*FutureTask<Integer> ft = new FutureTask<Integer>(new MyThread());
        new Thread(ft, "ThreadName-AA").start();
        System.out.println("=====主线程名测试======"+Thread.currentThread().getName());
        System.out.println(ft.get());*/
        FutureTask<Integer> ft= new FutureTask<Integer>(() -> {
            TimeUnit.SECONDS.sleep(3);//睡眠3秒
            System.out.println(Thread.currentThread().getName()
                    + "======" + "hello,lindaxia");
            return 200;//200表示执行成功

        });
        //启动两个线程
        FutureTask<Integer> ft2= new FutureTask<Integer>(new MyThread());
        new Thread(ft, "ThreadName-AA").start();
        new Thread(ft2, "ThreadName-BB").start();

        System.out.println("=====主线程名测试======"+Thread.currentThread().getName());
        //get()只输出一次,FutureTask只执行一次(ThreadName-AA/BB不确定谁执行)
        System.out.println(ft.get());
        System.out.println(ft2.get());

    }
}
打印结果:

在这里插入图片描述

测试代码3-1:

FutureTask方法isDone()可判断是否计算完(完成任务),true表示计算完,false表示没计算完。

 if(!ft2.isDone()){
            System.out.println("=====没计算完,等待中======");//false就打印
        }

 ☝上述分享来源个人总结,如果分享对您有帮忙,希望您积极转载;如果您有不同的见解,希望您积极留言,让我们一起探讨,您的鼓励将是我前进道路上一份助力,非常感谢!我会不定时更新相关技术动态,同时我也会不断完善自己,提升技术,希望与君同成长同进步!

☞本人博客:https://coding0110lin.blog.csdn.net/  欢迎转载,一起技术交流吧!

1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 、4下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合;、下载 4使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合;、 4下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。
1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.m或d论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 、1资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值