谷粒商城实战笔记-193~194-商城业务-多线程-线程池

news2024/9/20 12:37:13

文章目录

  • 一,193-商城业务-异步-异步复习
    • 1. 继承`Thread`类
    • 2. 实现`Runnable`接口
    • 3. 实现`Callable`接口结合`FutureTask`
    • 4. 使用线程池
  • 二,194-商城业务-异步-线程池详解
    • 1,线程池七大参数
    • 2,面试题
    • 3,Executors能创建的4中线程池
      • FixedThreadPool
      • CachedThreadPool
      • SingleThreadExecutor
      • ScheduledThreadPoolExecutor

一,193-商城业务-异步-异步复习

Java中使用线程的4种方式包括:

  • 继承Thread
  • 实现Runnable接口
  • 实现Callable接口结合FutureTask使用
  • 使用线程池。

1. 继承Thread

继承Thread类并重写run方法来定义线程执行的任务。这种方式简单直观,但存在一些限制。

代码示例

public class ThreadExample1 extends Thread {
    @Override
    public void run() {
        System.out.println("ThreadExample1 is running.");
    }
}

// 使用
ThreadExample1 thread = new ThreadExample1();
thread.start();

问题:继承Thread类会强制要求类继承自Thread,这限制了类的继承结构,因为Java不支持多重继承。

2. 实现Runnable接口

通过实现Runnable接口,可以避免继承Thread类的限制,因为Java允许一个类实现多个接口。

代码示例

public class RunnableExample1 implements Runnable {
    @Override
    public void run() {
        System.out.println("RunnableExample1 is running.");
    }
}

// 使用
RunnableExample1 runnable = new RunnableExample1();
new Thread(runnable).start();

问题:与继承Thread类类似,这种方式不能获取线程执行的返回值,也不能很好地控制资源。

3. 实现Callable接口结合FutureTask

Callable接口允许任务有返回值,并且可以通过FutureTask来管理线程的生命周期和结果。

代码示例

public class CallableExample1 implements Callable<Integer> {
    @Override
    public Integer call() {
        return 100;
    }
}

// 使用
FutureTask<Integer> futureTask = new FutureTask<>(new CallableExample1());
new Thread(futureTask).start();
try {
    Integer result = futureTask.get(); // 阻塞等待结果
    System.out.println("CallableExample1 returned: " + result);
} catch (InterruptedException | ExecutionException e) {
    e.printStackTrace();
}

问题:尽管这种方式可以获取返回值,但创建和管理线程的开销仍然存在。

4. 使用线程池

线程池提供了一种高效的方式来管理线程,它可以复用线程,减少创建和销毁线程的开销,同时可以控制并发级别。

代码示例

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

public class ThreadPoolExample {
    public static void main(String[] args) {
        ExecutorService executorService = Executors.newFixedThreadPool(10); // 创建线程池
        Runnable task = () -> System.out.println("Task is running in thread pool.");
        executorService.submit(task); // 提交任务到线程池

        // 执行完毕后关闭线程池
        executorService.shutdown();
    }
}

优势

  • 资源控制:线程池可以控制并发线程的数量,有效管理资源。
  • 性能稳定:通过复用线程,减少了线程创建和销毁的开销,提高了性能。
  • 易于管理:线程池提供了统一的接口来提交和管理任务,简化了代码。

在实际开发中,推荐使用线程池来执行多线程任务,因为它提供了更好的资源管理和性能优势。

前三种方式虽然在某些简单场景下可以使用,但在需要高效资源管理和复杂任务调度的现代应用程序中,它们往往不够灵活和高效。

二,194-商城业务-异步-线程池详解

1,线程池七大参数

线程池(ThreadPoolExecutor)是Java并发编程中用于管理线程的一个核心组件。它允许你复用线程,从而减少因频繁创建和销毁线程而带来的开销。以下是线程池的七个主要参数,这些参数在创建线程池时可以进行配置:

  1. corePoolSize:线程池的基本大小,即在没有任务执行时,线程池中保留的线程数量。如果允许核心线程超时(通过设置allowCoreThreadTimeOuttrue),则即使线程池中的线程是空闲的,它们也会在一定时间后终止。

  2. maximumPoolSize:线程池中允许的最大线程数。如果任务队列满了,线程池会尝试创建新的线程,直到达到这个数目。

  3. keepAliveTime:当线程池中的线程数量超过corePoolSize时,多余的空闲线程能等待新任务的最长时间。如果在这个时间内没有新任务到达,这些线程将被终止。

  4. unitkeepAliveTime参数的时间单位,常见的时间单位有TimeUnit.SECONDSTimeUnit.MILLISECONDS等。

  5. workQueue:一个阻塞队列,用于存储等待执行的任务。这个队列只保存通过execute(Runnable)方法提交的Runnable任务。

  6. threadFactory:一个线程工厂,用于创建新线程。通过自定义线程工厂,你可以对线程的创建过程进行控制,例如设置线程的名称、优先级等。

  7. handler:当线程池饱和(即线程数量达到maximumPoolSize且任务队列已满)时,使用的饱和策略。饱和策略定义了如何处理无法立即执行的任务,常见的饱和策略有:

    • ThreadPoolExecutor.AbortPolicy:抛出RejectedExecutionException来拒绝新任务的处理。
    • ThreadPoolExecutor.CallerRunsPolicy:调用执行任务的线程(提交任务的线程)来运行当前任务。
    • ThreadPoolExecutor.DiscardPolicy:直接丢弃无法处理的任务。
    • ThreadPoolExecutor.DiscardOldestPolicy:丢弃任务队列中最老的任务,然后尝试再次提交当前任务。

这些参数共同定义了线程池的行为和性能。正确地配置这些参数对于优化应用程序的并发性能至关重要。例如,如果corePoolSizemaximumPoolSize设置得太高,可能会导致资源竞争和上下文切换的开销;如果设置得太低,则可能无法充分利用多核处理器的优势。同样,workQueue的选择也会影响线程池的吞吐量和延迟特性。

2,面试题

下面是一个面试题。
在这里插入图片描述

当有100个并发请求进入线程池时,线程池会按照以下步骤进行操作:

  1. 首先,线程池会尝试使用其核心线程来处理请求。由于核心线程数为7,所以线程池会立即启动7个线程来处理这7个请求。

  2. 如果还有更多请求进来,并且核心线程都在忙于处理其他请求,那么这些额外的请求会被放入队列中等待处理。由于队列容量为50,所以最多可以存放50个请求。

  3. 当队列也满了后,线程池会尝试创建新的非核心线程来处理请求。由于最大线程数为20,所以最多可以创建13个非核心线程。

  4. 如果此时仍然有请求进来,并且所有的线程都在忙于处理其他请求,那么线程池可能会选择拒绝这些请求。具体的行为取决于线程池的饱和策略。

3,Executors能创建的4中线程池

在实际开发过程中,一般用Executors创建线程池,Executors相当于一个工厂类,创建各种各样的线程池对象。

  1. FixedThreadPool:

    • 类型:固定大小的线程池。
    • 特点:线程池中的线程数量是固定的。当一个线程完成任务后,它会从队列中获取新的任务来执行。这种线程池能够保证程序的资源占用相对稳定。
    • 用途:适用于需要控制线程数量的场景,如后台任务处理、定时任务等。
  2. CachedThreadPool:

    • 类型:可缓存的线程池。
    • 特点:线程池的大小没有限制,可以根据需要动态地调整线程的数量。空闲的线程会在一段时间后自动终止。
    • 用途:适用于执行大量短小的任务,如网络I/O操作、计算密集型任务等。
  3. SingleThreadExecutor:

    • 类型:单线程的线程池。
    • 特点:线程池只有一个线程,确保所有任务按照指定顺序执行。
    • 用途:适用于需要保证任务顺序执行的场景,例如数据更新、文件写入等。
  4. ScheduledThreadPoolExecutor:

    • 类型:支持定时任务的线程池。
    • 特点:线程池可以调度任务以定期或延迟的方式执行。
    • 用途:适用于需要定期执行任务或延时执行任务的场景,如计划任务、周期性检查等。

下面是这四种线程池的具体实现方式:

FixedThreadPool

ExecutorService fixedThreadPool = Executors.newFixedThreadPool(nThreads);

CachedThreadPool

ExecutorService cachedThreadPool = Executors.newCachedThreadPool();

SingleThreadExecutor

ExecutorService singleThreadExecutor = Executors.newSingleThreadExecutor();

ScheduledThreadPoolExecutor

ScheduledExecutorService scheduledThreadPool = Executors.newScheduledThreadPool(nThreads);

其中,nThreads 表示线程池中的线程数量。对于 newFixedThreadPoolnewScheduledThreadPool,这个值是必需的,而对于 newSingleThreadExecutornewCachedThreadPool,则不需要指定线程数量。

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

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

相关文章

个人经历分享如何用Python日入1K+,分享兼职网站和渠道!

大部分人主要通过接私活赚钱。我第一次接单是朋友介绍的&#xff0c;当时刚学Python&#xff0c;为一家公司爬数据&#xff0c;赚了一千多。从那之后逐渐熟练&#xff0c;常在假期接一些数据处理的单&#xff0c;很多时候兼职收入是主业收入的2~3倍。 附上我前两年的兼职接单记…

黑马头条vue2.0项目实战(十一)——功能优化(组件缓存、响应拦截器、路由跳转与权限管理)

1. 组件缓存 1.1 介绍 先来看一个问题&#xff1f; 从首页切换到我的&#xff0c;再从我的回到首页&#xff0c;我们发现首页重新渲染原来的状态没有了。 首先&#xff0c;这是正常的状态&#xff0c;并非问题&#xff0c;路由在切换的时候会销毁切出去的页面组件&#xff…

【vue讲解:vue3介绍、setup、ref、reactive、监听属性、生命周期、toRef、setup写法】

1 vue3介绍 # Vue3的变化-vue3完全兼容vue2---》但是vue3不建议用vue2的写法-拥抱TypeScript-之前咱们用的JavaScript---》ts完全兼容js- 组合式API和配置项APIvue2 是配置项apivue3 组合式api# vue4必须要用2 vue3项目创建和启动 # 创建vue3项目-vue-cli 官方不太建议用了…

【Java学习】方法的引用

所属专栏&#xff1a;Java学习 &#x1f341;1. 方法引用 方法的引用&#xff1a;把已经存在的方法拿来使用&#xff0c;当作函数式接口中抽象方法的方法体 " :: "是方法引用符 方法引用时需要注意&#xff1a; 1. 需要有函数式接口 2. 被引用的方法必须存在 3. …

4款专业高效的Win10 录屏工具大揭秘!

Win10 系统里面一般都有自带的录屏工具&#xff0c;用截图工具就可以实现录屏。但是呢&#xff0c;这个工具只适合录制一些简短的小片段。如果想要更多功能的录屏&#xff0c;还是需要使用到第三方的录屏工具&#xff0c;这次&#xff0c;我就跟大家分享4款专业的录屏软件。 1、…

拟南芥中基因家族序列的提取

1.拟南芥基因组数据的下载 phytozome 是一个收录植物基因组数据的网站&#xff0c;数据整理比较规范&#xff0c;已 经提供了去除可变剪切的 cds 和 protein 序列文件。只有 gff3 文件需要 过滤处理 2. 对拟南芥的注释文件gff3文件进行ID处理&#xff0c;最终得到以下4个文件 …

深度解析:.secret勒索病毒如何加密你的数据并勒索赎金

引言&#xff1a; 在当今这个数字化、信息化的时代&#xff0c;网络安全已成为一个不容忽视的重要议题。随着互联网的普及和技术的飞速发展&#xff0c;我们的生活、工作乃至整个社会的运转都越来越依赖于各种计算机系统和网络。然而&#xff0c;这种高度依赖也为我们带来了前…

硬件面试经典 100 题(51~70 题)

51、请列举您知道的覆铜板厂家。 生益、建滔。 52、示波器铭牌一般都会标识两个参数&#xff0c;比如泰克 TDS1002B 示波器标识的 60MHz 和 1GS/s&#xff0c;请解释这两个参数的含义。 60MHz 是指示波器的带宽&#xff0c;即正常可以测量 60MHz 频率以下的信号。 1GS/s 是指示…

鲲鹏920s 32核处理器linpack性能调优

1、BIOS参数调优 BIOS选项 设置值 Power Policy Performance Stream Write Mode Allocate share LLC CPU Prefetching Configuration Enabled Custom Refresh Rate 64ms Die Interleaving Disabled NUMA Enable SSBS Support Disabled 2、benchmark参数调优 主…

vue项目将px转成其他单位,如rem、cqw,postcss-pxtorem的使用

安装插件 新建配置文件.postcssrc.js // module.exports { // "plugins": { // "postcss-pxtorem": { // rootValue: 1,//必须和rem的初始值一致 // propList: [*], // // selectorBlackList: [ // // ant…

计算函数(c语言)

1.描述 //小乐乐学会了自定义函数&#xff0c;BoBo老师给他出了个问题&#xff0c;根据以下公式计算m的值。 // //其中 max3函数为计算三个数的最大值&#xff0c;如&#xff1a; max3(1, 2, 3) 返回结果为3。 //输入描述&#xff1a; //一行&#xff0c;输入三个整数&#xff…

3的幂计算

给定一个整数&#xff0c;写一个函数来判断它是否是 3 的幂次方。如果是&#xff0c;返回 true &#xff1b;否则&#xff0c;返回 false 。 整数 n 是 3 的幂次方需满足&#xff1a;存在整数 x 使得 n 3x。 示例 1&#xff1a; 输入&#xff1a;n 27 输出&#xff1a;tru…

SpringCloud天机学堂:学习计划与进度(四)

SpringCloud天机学堂&#xff1a;学习计划与进度&#xff08;四&#xff09; 文章目录 SpringCloud天机学堂&#xff1a;学习计划与进度&#xff08;四&#xff09;1、业务接口统计2、实现接口2.1、查询学习记录2.2、提交学习记录2.3、创建学习计划2.4、查询学习计划进度 1、业…

从零掌握keepalived合集

文章目录 keepalived简介keepalived部署keepalived基础设置主配置文件修改独立子配置文件实现实现日志分离 企业应用实例抢占式与非抢占式抢占式非抢占式 VIP单波配置消息通知脚本配置 实现IPVS高可用keepalivedlvs实现keepaliveshaproxy实现 keepalived简介 keepalived基于VR…

GAMES104:07游戏中渲染管线、后处理和其他的一切-学习笔记

文章目录 前言一&#xff0c;Ambient Occlusion环境光遮蔽1.1 Precomputed AO1.2 Screen Space Ambient Occlusion(SSAO)1.3 Horizon-based Ambient Occlusion(HBAO)1.4 Ground Truth-based Ambient Occlusion(GTAO)1.5 Rat-Tracing Ambient Occlusion 二&#xff0c;雾效2.1 D…

Java MessagePack序列化工具(适配Unity)

Java MessagePack序列化工具&#xff08;适配Unity&#xff09; 前言项目代码编写 结 前言 前后端统一用MessagePack&#xff0c;结果序列化的结果不一样&#xff0c;发现C#侧需要给每个类增加描述字段数量的Head&#xff0c;而Java却不用&#xff0c;所以在Java侧封装一下序列…

51系列LY-51S出现下载失败·的解法

1.他的下载电路是特殊设计的 一般连接1&#xff0c;2&#xff0c;另外的接口2&#xff0c;3一般不接&#xff0c;而且2&#xff0c;3的功能是用来diy自动下载电路的&#xff0c;你接上2&#xff0c;3又没独特的下载电路会一直复位

进程池详解

目录 进程池 1、什么是进程池&#xff1f; 2、实现进程池 &#xff08;1&#xff09;相关函数&#xff1a; pipe函数&#xff1a; write函数 read函数 waitpid函数 &#xff08;2&#xff09;代码实现面向过程进程池 Task.hpp processPool.cc 3、注意事项 进程池 …

坚鹏讲人才第12期:引领数字化未来—数字化人才与导师共赢之路

坚鹏讲人才第12期&#xff1a;引领数字化未来—数字化人才与导师共赢之路 ——抢占名额先机 成为坚鹏弟子 加速数字化转型 数字化浪潮汹涌而至&#xff0c;你是否感到迷茫、困惑、焦虑&#xff1f;想不想一脚油门冲进未来&#xff0c;和我一同探寻数字化人才的奥秘&#xf…

【迅为电子】RK3568驱动指南|第十七篇 串口-第202章 串口编程

瑞芯微RK3568芯片是一款定位中高端的通用型SOC&#xff0c;采用22nm制程工艺&#xff0c;搭载一颗四核Cortex-A55处理器和Mali G52 2EE 图形处理器。RK3568 支持4K 解码和 1080P 编码&#xff0c;支持SATA/PCIE/USB3.0 外围接口。RK3568内置独立NPU&#xff0c;可用于轻量级人工…