线程池应用(四)

news2024/11/19 16:39:49

线程池应用

  • 线程池
    • 线程池应用
  • 多线程应用
    • 同步和异步
      • 1. 需要等待结果
        • 1. join 实现(同步)
        • 2. Future 实现(同步)
        • 3.CompletableFuture 实现(异步)
        • 4. BlockingQueue 实现(异步)
      • 2. 不需等待结果
        • 1. 普通线程实现
        • 2. 线程池实现
        • 3. CompletableFuture 实现

线程池

<dependency>
    <groupId>com.google.guava</groupId>
    <artifactId>guava</artifactId>
    <version>30.0-jre</version>
</dependency>
import com.google.common.util.concurrent.ThreadFactoryBuilder;

 // 自定义线程池
static ExecutorService executorService = new ThreadPoolExecutor(3, 5, 100, TimeUnit.MILLISECONDS,
        new ArrayBlockingQueue<Runnable>(20),
        new ThreadFactoryBuilder().setNameFormat("log-thread-pool-%d").build(),
        new ThreadPoolExecutor.AbortPolicy());

线程池应用

public class ThreadPoolExecutorController {

    @GetMapping("/")
    public ResultVO testTheadPool() throws ExecutionException, InterruptedException {
        ThreadPoolExecutor threadPoolExecutor = ThreadPoolExecutorUtils.getThreadPoolExecutor();
        ArrayList<BuildXmlTask> list = Lists.newArrayList();
        for (int i = 0; i < 10; i++) {
            BuildXmlTask buildXmlTask = new BuildXmlTask();
            list.add(buildXmlTask);
        }

        List<Future<BuildXmlDTO>> futures = threadPoolExecutor.invokeAll(list);
        ArrayList<BuildXmlDTO> buildXmlDTOS = Lists.newArrayList();
        for (Future<BuildXmlDTO> future : futures) {
            if (future != null) {
                buildXmlDTOS.add(future.get());
            }
        }

        return ResultVO.ok(buildXmlDTOS);
    }
}

@Data
class BuildXmlDTO {
    private String code;
    private String msg;
}

@Slf4j
class BuildXmlTask implements Callable<BuildXmlDTO> {

    @Override
    public BuildXmlDTO call() throws Exception {
        log.info("{}",Thread.currentThread().getName());
        BuildXmlDTO buildXmlDTO = new BuildXmlDTO();
        buildXmlDTO.setCode("200");
        buildXmlDTO.setMsg("发送成功");
        return buildXmlDTO;
    }
}

多线程应用

同步和异步

同步和异步通常来形容一次方法调用,同步方法调用一旦开始,调用者必须等到方法调用返回后,才能继续后续的行为。异步方法调用更像一个消息传递,一旦开始,方法调用就会立即返回,调用者就可以继续后续的操作。而异步方法通常会在另外一个线程中“真实”地执行。整个过程,不会阻碍调用者的工作。

1. 需要等待结果

这时既可以使用同步处理,也可以使用异步来处理

1. join 实现(同步)

@Slf4j
public class demo01 {
    static int result = 0;

    public static void main(String[] args) throws InterruptedException {
        log.info("main开始");
        Thread thread = new Thread(() -> {
            log.info("子线程开始");
            try {
                TimeUnit.SECONDS.sleep(2);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            result = 10;
            log.info("子线程结束");
        },"join方法同步线程");
        thread.start();
        thread.join();
        log.info("结果为:{}", result);
    }
}

输出
在这里插入图片描述

缺点:

1、需要外部共享变量,不符合面向对象封装的思想

2、必须等待线程结束,不能配合线程池使用

2. Future 实现(同步)

@Slf4j
public class demo02 {
    public static void main(String[] args) throws ExecutionException, InterruptedException {
        log.info("main线程开始");
        FutureTask<Integer> result = new FutureTask<>(() -> {
            log.info("任务线程开始");
            TimeUnit.SECONDS.sleep(1);
            log.info("任务线程结束");
            return 10;
        });
        new Thread(result, "Future实现(同步)").start();
        log.info("结果为:{}", result.get());
        log.info("main线程结束");
    }
}

在这里插入图片描述

  • 规避了使用 join 之前的缺点

  • 可以方便配合线程池使用

private static void userThreadPool() throws ExecutionException, InterruptedException {
    ExecutorService executorService = Executors.newFixedThreadPool(1);
    log.info("main线程开始");
    // execute(): 无返回值, submit(): 有返回值
    Future<?> result = executorService.submit(() -> {
        log.info("开始");
        TimeUnit.SECONDS.sleep(1);
        log.info("结束");
        return 10;
    });
    log.info("结果为:{}, result 的类型:{}", result.get(), result.getClass());
    executorService.shutdown();
    log.info("main线程结束");
}

在这里插入图片描述

  • 仍然是 main 线程接收结果

  • get 方法是让调用线程同步等待

3.CompletableFuture 实现(异步)

@Slf4j
public class demo03 {
    public static void main(String[] args) {
        // 进行计算的线程池
        ExecutorService computeService = Executors.newFixedThreadPool(1);
        // 接收结果的线程池
        ExecutorService resultService = Executors.newFixedThreadPool(1);
        log.info("main线程开始");
        CompletableFuture.supplyAsync(() -> {
            log.info("子线程开始");
            try {
                TimeUnit.SECONDS.sleep(1);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            log.info("子线程结束");
            return 10;
        }, computeService).thenAcceptAsync((result) -> {
            log.info("结果为:{}", result);
        }, resultService);
        log.info("main线程结束");
    }
}

在这里插入图片描述

1、可以让调用线程异步处理结果,实际是其他线程去同步等待

2、可以方便地分离不同职责的线程池

3、以任务为中心,而不是以线程为中心

4. BlockingQueue 实现(异步)

@Slf4j
public class demo04 {
    public static void main(String[] args) throws InterruptedException {
        ExecutorService consumer = Executors.newFixedThreadPool(1);
        ExecutorService producer = Executors.newFixedThreadPool(1);
        BlockingQueue<Integer> queue = new SynchronousQueue<>();
        log.info("main线程开始");
        producer.submit(() -> {
            log.info("生产出添加任务开始");
            try {
                TimeUnit.SECONDS.sleep(1);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            log.info("生产出添加任务结束");
            try {
                queue.put(10);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        });
        consumer.submit(() -> {
            log.info("消费者消费 开始");
            try {
                Integer result = queue.take();
                log.info("结果为:{}", result);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        });

        log.info("main线程结束");
    }
}

在这里插入图片描述

2. 不需等待结果

这时最好是使用异步来处理

1. 普通线程实现

@Slf4j
public class demo05 {
    public static void main(String[] args) throws InterruptedException {
		read();
        log.info("do other things ...");
    }

    public static void read() throws InterruptedException {
        String shortName = "a.txt";
        long start = System.currentTimeMillis();
        log.info("read [{}] start ...", shortName);
        TimeUnit.SECONDS.sleep(4);
        long end = System.currentTimeMillis();
        log.info("read [{}] end ... cost: {} ms", shortName, end - start);
    }
}

没有用线程时,方法的调用是同步的:
在这里插入图片描述

使用了线程后,方法的调用是异步的:

// 1、普通线程
new Thread(()->{
    try {
        read();
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
}).start();
log.info("do other things ...");

输出

在这里插入图片描述

2. 线程池实现

// 2、线程池实现
ExecutorService service = Executors.newFixedThreadPool(1);
service.execute(()->{
    try {
        read();
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
});
log.info("do other things ...");
service.shutdown();

在这里插入图片描述

3. CompletableFuture 实现

// 3、CompletableFuture 实现
CompletableFuture.runAsync(() -> {
    try {
        read();
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
},service);
service.shutdown();
log.info("do other things ...");

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/82124.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

5分钟搞定,实现 定时任务 的五种方案!

我们在实际开发中&#xff0c;多多少少都会用到定时任务来处理一些问题。 比如金融项目中的对账&#xff0c;每天定时对昨天的账务进行核对&#xff0c;每个月初对上个月的账务进行核对等。 还比如&#xff0c;我们需要处理一些老数据迁移&#xff0c;修复一些新项目和老项目…

基于java+springboot+mybatis+vue+mysql的财务管理系统

项目介绍 随着信息技术和网络技术的飞速发展&#xff0c;人类已进入全新信息化时代&#xff0c;传统管理技术已无法高效&#xff0c;便捷地管理信息。为了迎合时代需求&#xff0c;优化管理效率&#xff0c;各种各样的管理系统应运而生&#xff0c;各行各业相继进入信息管理时…

CI24R1/SI24R1 2.4G无线传输技术--无线门铃

无线门铃是一种基于2.4G无线传输技术的智能家居产品&#xff0c;主要用于亲朋好友探访的语音提醒功能。此次方案采用2.4G无线通信设计&#xff0c;室内和室外子母机组网&#xff0c;在智能家居及办公场所等方面得到广泛的应用。 一、应用场景 适用于居民社区、家庭、公寓、酒店…

2-2-3-5-5、Disruptor详解

目录简介juc包下的队列存在的问题设计方案RingBuffer数据结构数据存取方案常用等待策略写数据流程单线程&#xff08;一个生产者&#xff09;多线程&#xff08;多个生产者&#xff09;多个消费者读数据多个生产者写数据核心概念使用构造器引入依赖单生产者单消费者模式创建Eve…

微信公众号开发——接收用户消息(图文、语言、上报位置、关注、取消关注)及自动回复

&#x1f60a; 作者&#xff1a; 一恍过去&#x1f496; 主页&#xff1a; https://blog.csdn.net/zhuocailing3390&#x1f38a; 社区&#xff1a; Java技术栈交流&#x1f389; 主题&#xff1a; 微信公众号开发——接收用户消息(图文、语言、上报位置、关注、取消关注)及…

推动MRO工业品数字化基建升级,数商云采购系统赋能企业采购数字化管理

MRO工业品是工业生产中的重要组成部分&#xff0c;经历了十余年的发展成长&#xff0c;市场规模持续增长&#xff0c;然而据数据显示&#xff0c;MRO工业品市场的线上渗透率仍停留在个位数&#xff0c;这意味着MRO工业品数字化采购仍有巨大的发展空间。 MRO工业品行业发展受困…

非零基础自学Golang 第1章 走进Go 1.1 Go编程语言概述 1.1.1 Go 的历史

非零基础自学Golang 文章目录非零基础自学Golang第1章 走进Go1.1 Go编程语言概述1.1.1 Go 的历史第1章 走进Go 1.1 Go编程语言概述 Go语言也叫Golang&#xff0c;是由谷歌&#xff08;Google&#xff09;公司在2007年推出的一款静态编译型语言。Go语言高效、简洁、容易上手&a…

上海诺基亚贝尔-S-010W-AV2B卡刷固件包

上海诺基亚贝尔-S-010W-AV2B卡刷固件包 固件特点&#xff1a; 1、修改dns&#xff0c;三网通用&#xff1b; 2、开放原厂固件屏蔽的市场安装和u盘安装apk&#xff1b; 3、无开机广告&#xff0c;无系统更新&#xff0c;不在被强制升级&#xff1b; 4、大量精简内置的没用的…

最新版Crack:MailBee.NET 2022最后版

MailBee.NET Items Package 包括 SMTP、POP3、IMAP、EWS、Security、Antispam、Outlook Converter、Address Validator、PDF 部件&#xff0c;以及作为免费功能的 BounceMail、HTML、MIME、ICalVCard 部件。MailBee.NET Objects是一组功能强大且功能丰富的 .NET 元素&#xff0…

基于nodejs如何爬取csdn上自己的文章

当你想把自己在csdn上写的文章转为hexo上可以发布的文章或是将文章写入自己的数据库时,可以用到 将所有博客数据写入数据库 获取你的文章的分页接口: 在浏览自己的所有文章时,我们不难发现,文章的数据是往下滑动到底时,才会刷新出新的数据, 那么此时肯定是发送了一个请求来获…

一篇文章教你实战Docker容器数据卷

在上一篇中&#xff0c;咱们对Docker中的容器数据卷做了介绍。已经知道了容器数据卷是什么&#xff1f;能干什么用。那么本篇咱们就来实战容器数据卷&#xff0c;Docker容器数据卷案例主要做以下三个案例 1&#xff1a;宿主机(也就是Docker所安装的机器)与容器之间的映射-让Do…

LeetCode 538. 把二叉搜索树转换为累加树(C++)

标签&#xff1a;二叉树搜索 深度优先遍历 二叉树 思路一&#xff1a;递归实现反向中序遍历&#xff0c;并累加递归过程中的根的值 思路二&#xff1a;使用迭代&#xff0c;给每个根节点添加一个反向中序遍历的前驱节点。 原题链接&#xff1a;https://leetcode.cn/problems/co…

数据分析业务场景 | CTR预估

一.概况 定义 是推荐中最核心的算法之一 对每次广告的点击情况做出预测&#xff0c;预测用户是点击还是不点击 就是预测点击与否的而分类算法&#xff0c;成功的关键之一就是样本的准确性 对于正样本&#xff0c;一般可发挥的空间不是很大&#xff0c;最多就是卡一个停留时…

LinkedList源码解析

LinkedList源码解析 简介 LinkedList 是一个双向链表&#xff08;内部是 Node 节点&#xff09;实现的 List&#xff0c;并且还实现了 Deque 接口&#xff0c;它除了作为 List 使用&#xff0c;还可以作为队列或者栈来使用。 这样看来&#xff0c;LinkedList 简直就是个全能…

【文字版】津津有味:感染新冠后没食欲,那咱也得吃饭啊!

点击文末“阅读原文”即可收听本期节目剪辑、音频 / 朱峰 编辑 / 姝琦 SandLiu监制 / 姝琦 文案 / 粒粒 产品统筹 / bobo你阳了吗&#xff1f;你嗓子疼吗&#xff1f;你的食欲还好吗&#xff1f;没有什么比好好吃饭更重要&#xff0c;生病的时候尤其是。营养对健康而言是预防…

浏览器上的Cookies有什么用?超级浏览器防关联如何实现?

Cookies是浏览器的指纹信息之一&#xff0c;它是一种文本文件&#xff0c;是网站为了辨别用户身份&#xff0c;对用户进行记录并由户客户端计算机进行暂时或永久保存的信息。一般情况下&#xff0c;网站对浏览器的指纹的记录主要是依靠Cookies来实现的。因为超级浏览器来可以生…

[附源码]JAVA毕业设计英语网站(系统+LW)

[附源码]JAVA毕业设计英语网站&#xff08;系统LW&#xff09; 项目运行 环境项配置&#xff1a; Jdk1.8 Tomcat8.5 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xf…

[附源码]Python计算机毕业设计大学生健康系统Django(程序+LW)

该项目含有源码、文档、程序、数据库、配套开发软件、软件安装教程 项目运行 环境配置&#xff1a; Pychram社区版 python3.7.7 Mysql5.7 HBuilderXlist pipNavicat11Djangonodejs。 项目技术&#xff1a; django python Vue 等等组成&#xff0c;B/S模式 pychram管理等…

c#和Python交互,完美解决Python调用OpenCV等第三方库以及分发时需配置python环境的问题

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录前言一、问题分析二、解决方案第一个问题第二个问题三、结果及源码四、总结前言 关于C#如何调用Python&#xff0c;网上提供了很多解决方案&#xff0c;有用ironPyt…

react组件深度解读

五、React 核心是组件 在 React 中&#xff0c;我们使用组件&#xff08;有状态、可组合、可重用&#xff09;来描述 UI 。 在任何编程语言中&#xff0c;你都可以将组件视为简单的函数。 React 组件也一样&#xff0c; 它的输入是 props&#xff0c;输出是关于 UI 的描述。我…