五、Callable与Future模式

本文详细介绍了如何合理配置线程池以适应IO密集型和CPU密集型任务,以及Java中Callable和Future模式的使用。通过示例代码展示了如何利用Future模式在不阻塞主线程的情况下获取异步任务的结果,提高程序执行效率。
摘要由CSDN通过智能技术生成

一、合理配置线程池

1、IO密集型

  • 任务需要大量的IO阻塞,要解决阻塞问题,可以使用多线程技术
  • 为了保证CPU的运算能力,不会浪费资源,配置线程数=2*CPU核数

2、CPU密集型

  • 该任务执行的时候不会产生大量的IO阻塞,CPU运行的时候速度特别快
  • 配置线程数=CPU核数

二、Callable

  • 在Java中,创建线程一般有两种方式,一种是继承Thread类,一种是实现Runnable接口。
    • 然而,这两种方式的缺点是在线程任务执行结束后,无法获取执行结果。
    • 我们一般只能采用共享变量或共享存储区以及线程通信的方式实现获得任务结果的目的。
    • 而这样要获取run方法的执行结果,必须要执行完毕后才能获取到结果,整个程序是阻塞的
  • 不过,Java中,也提供了使用Callable和Future来实现获取任务结果的操作
    • Callable用来执行任务,产生结果,而Future用来获得结果
public class App {
    public static void main(String[] args) throws ExecutionException, InterruptedException {
        ExecutorService newCachedThreadPool = Executors.newCachedThreadPool();
        Future<String> submit = newCachedThreadPool.submit(new TaskCallable());
        System.out.println("1.主线程开始执行...");
        String result = submit.get();
        System.out.println("2.result:" + result);
    }
}

class TaskCallable implements Callable<String> {
    @Override
    public String call() throws Exception {
        System.out.println("3.正在执行任务,需要等待五秒时间,执行任务开始");
        Thread.sleep(5000);
        System.out.println("4.正在执行任务,需要等待五秒时间,执行任务结束");
        return "Done";
    }
}

在这里插入图片描述

三、Future模式

  • Future模式的核心在于:
    • 去除了主函数的等待时间,并使得原本需要等待的时间段可以用于处理其他业务逻辑

A和B两个线程,如果A需要B的执行结果,那么这个A线程不需要等待B执行完毕后,才能拿到结果
使用Future模式可以先拿到一个未来的Future,等B有结果时再取真实的结果

四、手动实现future模式

  • 源码执行分析
    • 1、从main函数开始FutureClient futureClient = new FutureClient();执行
    • 2、调用futureClient.request后,实例化了futureData对象
    • 3、并且开启了一个线程,调用了realData的构造函数
    • 4、而realData的构造函数执行了sleep=3000的操作
    • 5、然后调用了futureData.setRedData(realData);获取数据后来唤醒线程
    • 6、注意:main函数中的String result = request.getRequest();这个是在主线程执行的
      • 执行了request.getRequest()的时候,此时还没有获取到数据,所以线程处于wait状态

1、Data类

//公共data数据结果
public abstract class Data {

    //返回线程执行结果
    public abstract String getRequest();
}

2、RealData类

//获取真实数据
public class RealData extends Data{

    private String requestData;

    public RealData(String requestData){
        System.out.println("正在使用data进行网络请求,data:"+ requestData + ",开始...");
        try{
            Thread.sleep(3000);
        }catch (Exception e){

        }
        System.out.println("操作执行完毕...获取到结果");
        //获取
        this.requestData = "Done";
    }

    @Override
    public String getRequest() {
        return requestData;
    }
}

3、FutureData类

//当有线程想要获取RealData的时候,程序会被阻塞。等到RealData被注入才会使用getReal()方法
public class FutureData extends Data {

    //读取结果
    private boolean FLAG = false;

    private RealData realData;

    //读取data数据
    public synchronized void setRedData(RealData realData){
        //如果已经取到结果,直接返回
        if(FLAG){
            return;
        }
        //如果flag为false,没有获取到数据,传递realData对象
        this.realData = realData;
        FLAG = true;
        notify();
    }

    @Override
    public synchronized String getRequest(){
        while (!FLAG){
            try {
                wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        return realData.getRequest();
    }
}

4、FutureClient

public class FutureClient {

    //
    public Data submit(String requestData){
        final FutureData futureData = new FutureData();
        new Thread(new Runnable() {
            @Override
            public void run() {
                //阻塞
                RealData realData = new RealData("60030");
                futureData.setRedData(realData);
            }
        }).start();
        return futureData;
    }
}

5、Main函数

public class Main {
    public static void main(String[] args) {
        FutureClient futureClient = new FutureClient();
        Data request = futureClient.request("123213");
        System.out.println("main.数据发送成功.");
        System.out.println("主线程执行其他任务");
        String result = request.getRequest();
        System.out.println("主线程获取result:" + result);
    }
}

执行截图:
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

无休止符

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值