天去面试的时候,遇到一个问题。我三个任务,ABC,我怎么让A执行完执行B,B执行完执行C 3个并行线程,如何解决。程池的核心运行原理和参数。

这篇具有很好参考价值的文章主要介绍了天去面试的时候,遇到一个问题。我三个任务,ABC,我怎么让A执行完执行B,B执行完执行C 3个并行线程,如何解决。程池的核心运行原理和参数。。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

今天去面试的时候,遇到一个问题。我三个任务,ABC,我怎么让A执行完执行B,B执行完执行C 3个并行线程,如何解决。程池的核心运行原理和参数。

1.线程池核心的参数
1.线程核心数- 线程池中始终保持的活动线程数量。
2.最大线程数- 线程池能够容纳的最大线程数量。
3.等待队列- 用于存储等待执行的任务的队列。
4.线程存活时间- 没有任务额外的线程会保持活动状态的时间。
5.时间单位-可以是毫秒,秒。
6.线程工厂- 创建一个线程工厂。
7.拒绝策略- 线程池的任务队列已满,新任务的处理方式。
举个列子:
private static ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(10, 10,
            0L, TimeUnit.MILLISECONDS,
            new LinkedBlockingQueue<>(),
            new ThreadFactoryBuilder()
                    .setThreadFactory(new DefaultThreadFactory("task-inspection"))
                    .setUncaughtExceptionHandler((t, e) -> log.error("{}", t, e)).build()
    );   
2.线程池的运行原理
想象你是一家快餐店的老板,你的店里经常有顾客需要服务。你有一些员工,每个员工可以为顾客制作食物。但是,你不可能每次有顾客来的时候都去雇佣新员工,因为雇佣和解雇都需要花费时间和金钱。
于是,你决定采用一种聪明的方式来管理员工:你雇佣了一组员工,让他们一直待在店里,准备着做食物的工作。当有顾客来了,你只需要把订单交给员工,他们就会按照订单制作食物。这样,你节省了雇佣和解雇的麻烦,员工也可以充分利用自己的时间,不必一直等着顾客。
线程池就像是这家快餐店的员工组合。线程池会事先创建一些线程,就像员工待在店里准备做工作。当有任务需要执行时,就把任务交给线程池,就像把订单交给员工。线程池的线程会按顺序执行任务,然后再继续执行下一个任务,就像员工按照订单制作食物。
线程池的运行原理可以分为以下几个步骤:
  1. 线程池的创建:在程序初始化或需要使用线程池时,创建一个线程池对象。这个线程池对象会根据配置参数来初始化一定数量的线程,以及一个任务队列用于存放待执行的任务。
  2. 任务提交:当有任务需要执行时,应用程序通过将任务对象提交给线程池。这些任务会被放入任务队列中,等待线程池中的空闲线程来执行。
  3. 线程池的管理:线程池会根据配置的核心线程数和最大线程数来管理线程的数量。如果任务数量小于核心线程数,线程池会创建新线程来执行任务。如果任务数量大于核心线程数,但小于最大线程数,线程池会将任务放入任务队列中等待执行,而不会创建新线程。如果任务数量超过最大线程数,线程池会根据拒绝策略来处理任务,例如丢弃任务或抛出异常。
  4. 任务执行:线程池中的线程会从任务队列中取出任务并执行。线程池会不断地从任务队列中取任务,确保所有任务都得到执行。执行完任务后,线程会继续从队列中取下一个任务。
  5. 线程回收:在任务执行完毕后,线程池会根据一定的策略来决定是否回收线程。如果线程池的活动线程数量超过核心线程数,空闲的线程会在一定时间内保持活动状态,以备下次任务使用。如果空闲时间超过一定阈值,额外的线程可能会被终止以节省资源。
3.如何解决这样的问题,我考虑使用 CountDownLatch
1、为什么我会使用 CountDownLatch ?
在上一家公司实际开发过程当中,就遇到过并行的问题。那个时候是要多个任务都执行,但是并没有去保证他的一个执行的顺序。于是我们就使用到了CountDownLatch 使用计数器去判断这些所有的业务逻辑是否都执行完毕,从而进行下一步操作。
部分的代码代码如下:
private static ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(10, 10,
            0L, TimeUnit.MILLISECONDS,
            new LinkedBlockingQueue<>(),
            new ThreadFactoryBuilder()
                    .setThreadFactory(new DefaultThreadFactory("task-inspection"))
                    .setUncaughtExceptionHandler((t, e) -> log.error("{}", t, e)).build()
    );   


@Override
    @Transactional(rollbackFor = Exception.class)
    public void asyncInitiatingInspection(InspectionRecordsBO bo) {
        CountDownLatch countDownLatch = new CountDownLatch(inspectionBaseServiceList.size());
        inspectionBaseServiceList.forEach(inspectionBaseService -> {
            threadPoolExecutor.execute(() -> {
                try {
                    MDCUtil.putMDCKey(IdGenUtils.generateRequestId());
                    inspectionBaseService.addInspection(bo);
                } catch (Exception e) {
                    log.error("发起巡检信息失败类:{},发起巡检信息失败:{}", inspectionBaseService.getClass().getName(), e);
                } finally {
                    countDownLatch.countDown();
                    MDCUtil.removeMDCKey();
                }
            });
        });
        try {
            // 等待所有线程执行完毕
            countDownLatch.await();
        } catch (InterruptedException e) {
            log.error("线程计数器失败:" + e);
            Thread.currentThread().interrupt();
        }
        // 判断是否所有巡检已完
        this.updateInspectionResult(bo);
    }
2、什么是 CountDownLatch ?

CountDownLatch 是 Java 标准库中的一个同步工具,用于在多个线程之间进行协调和控制。它可以帮助一个或多个线程等待其他线程完成一组操作,然后再继续执行。

你可以将 CountDownLatch 想象成一个倒计时计数器,可以设置一个初始计数值,然后多个线程可以等待这个计数器减为零,之后再继续执行。

主要的操作方法有两个:

  • await() 方法:调用这个方法的线程会被阻塞,直到计数器减到零。其他线程完成一定操作后,调用 countDown() 方法来减小计数器的值。当计数器变为零时,被阻塞的线程会继续执行。
  • countDown() 方法:这个方法用于减小计数器的值。当一个线程完成了一个操作,可以调用这个方法来减小计数器的值。

CountDownLatch 在多线程编程中常常用于实现“等待所有线程完成某个任务后再继续”的场景。例如,在主线程中等待多个子线程都完成某些操作后再进行下一步操作。

3.解决方案
package com.aq.test;

import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class TestCountDownLatch {
    public static void main(String[] args) {
        CountDownLatch latch1 = new CountDownLatch(0);
        CountDownLatch latch2 = new CountDownLatch(1);
        CountDownLatch latch3 = new CountDownLatch(1);

        ExecutorService executor = Executors.newFixedThreadPool(3);

        executor.submit(() -> {
            try {
                latch1.await();
                System.out.println("线程A执行完毕");

                // todo 业务逻辑

            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
            } finally {
                latch2.countDown();
            }
        });

        executor.submit(() -> {
            try {
                latch2.await();
                System.out.println("线程B执行完毕");

                // todo 业务逻辑

            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
            } finally {
                latch3.countDown();
            }
        });

        executor.submit(() -> {
            try {
                latch3.await();
                System.out.println("线程C执行完毕");

                // todo 业务逻辑


            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
            }
        });

        latch1.countDown();

        executor.shutdown();
    }
}

我们使用了三个 CountDownLatch,分别用于控制三个线程的执行顺序。每个线程在执行之前都会通过 await 方法等待前一个线程的 CountDownLatch 计数减为0,然后执行自己的任务。

通过适时的 countDown 调用,我们确保了线程的顺序执行。在这个例子中,线程A会先执行,然后是线程B,最后是线程C。文章来源地址https://www.toymoban.com/news/detail-681451.html

总结,通过自己的理解和在网上寻找答案。以上就是我对于这几个问题的解决方案和解决思路。

到了这里,关于天去面试的时候,遇到一个问题。我三个任务,ABC,我怎么让A执行完执行B,B执行完执行C 3个并行线程,如何解决。程池的核心运行原理和参数。的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包赞助服务器费用

相关文章

  • 遇到本地跨域问题时候webpack本地开发配置proxy的方式

    假设现在有两个后端服务user和excel,接口请求地址为http://100.100.200.103:8012/pc/cfsm/web-user/getUser/id=2233?timestamp=234423322 本地调用该地址则为 localhost:8080访问http://100.100.200.103:8012/cfsm域,出现跨域问题, 解决方式为: webpack.dev.config.js中proxy写法如上, 系统服务可能会很多,所以给所

    2024年02月15日
    浏览(8)
  • 多线程知识:三个线程如何交替打印ABC循环100次

    本文博主给大家讲解一道网上非常经典的多线程面试题目。关于三个线程如何交替打印ABC循环100次的问题。 下文实现代码都基于Java代码在单个JVM内实现。 给定三个线程,分别命名为A、B、C,要求这三个线程按照顺序交替打印ABC,每个字母打印100次,最终输出结果为: 推荐博

    2024年02月12日
    浏览(7)
  • 【练习】条件变量:创建三个线程 id号为ABC,三个线程循环打印自己的ID号,运行顺序为 ABCABC

    题目: 创建三个线程 id号为ABC,三个线程循环打印自己的ID号,运行顺序为 ABCABC...... 要求使用条件变量 运行结果:死循环输出ABCn

    2024年02月14日
    浏览(9)
  • 在运行makefile文件的时候遇到 /bin/sh: 1: XXXXX: not found问题解决

    在运行makefile文件的时候遇到 /bin/sh: 1: XXXXX: not found问题解决

    解决方案  1、命令行操作可以正常操作,在makefile操作出现 /bin/sh: 1: XXXXX: not found 问题; 2、先  which  XXXXX 找到命令绝对路径; 3、在makefile内 XXXXX 前加上绝对路径 以下是我遇到的问题及我结局时候的操作流程: 1、首先描述问题情况 在使用makefile操作的时候提示编译器找不

    2023年04月17日
    浏览(11)
  • 昨天面试的时候被提问到的问题集合。

    昨天面试的时候被提问到的问题集合。

    1、vue的双向绑定原理是什么?里面的关键点在哪里? 2、实现水平垂直居中的方式? 3、常用伪元素有哪一些? 4、移动端如何适配不同屏幕尺寸? 5、本地存储有哪一些?他们三者有什么区别? 6、JS的数据类型?如何判断js的数据类型? 7、说一下ES6的新特性有哪些? 8、Let、

    2024年02月10日
    浏览(11)
  • 关于Qt编译android时候一个问题

    关于Qt编译android时候一个问题

    搞了三四天,搞的快崩溃了,问题提示为 修改问题 找到这个文件 注释下面的四行数据

    2024年02月16日
    浏览(6)
  • 三个稠密矩阵A,B,C的乘积ABC,假设三个矩阵的尺寸分别为mn,np,pq,且m<n<p<q,以下计算顺序效率最高的是

    三个稠密矩阵A,B,C的乘积ABC,假设三个矩阵的尺寸分别为mn,np,pq,且m<n<p<q,以下计算顺序效率最高的是

    提示: 在深度学习中,涉及到大量矩阵相乘,现在需要计算三个稠密矩阵A,B,C的乘积ABC,假设三个矩阵的尺寸分别为m n,n p,p*q,且mnpq,以下计算顺序效率最高的是:() A(BC) (AB)C (AC)B 所有效率都相同 矩阵乘积数学公式: ​ 假设存在两个矩阵A为m×n矩阵,B为k×l矩阵,若需要计

    2024年02月13日
    浏览(6)
  • 99%网工都会遇到的经典面试问题

    三次握手: 第一步:A向B发送一个SYN报文表示希望建立连接 第二步:B收到A发过来的数据包后,通过SYN得知这是一个建立连接的请求,于是发送ACK确认,由于TCP的全双工模式,故B向A还应该发送一个SYN报文,表示希望和A建立连接第三步:A收到B发送来的SYN报文后,A向B发送ACK表示A收

    2024年02月08日
    浏览(6)
  • C语言中关于printf()输出的时候的一个出栈入栈问题

    先看一段代码,可以自己尝试一下,反正我当时尝试的时候好多搞不懂, 不过现在搞懂了,里面牵扯到了一个入栈和出栈的问题,

    2024年02月09日
    浏览(6)
  • 遇到了一个跨域问题

    我的前端运行时 所在的端口是  localhost:7000, 后端所在的端口是 localhost:8080 我想 在前端像后端发送请求,获取数据。但是浏览器报错,因为不同源。 因此,解决方案如下: 在 Vue.js 应用程序中,你可以使用代理(Proxy)来解决跨域问题。代理允许你将请求发送到另一个域名

    2024年02月08日
    浏览(8)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包