高并发与多线程学习七(二)

多线程和高并发介绍 多线程和高并发介绍 文章目录多线程和高并发介绍前言一、什么是多线程?1.多线程介绍2.多线程实现原理?3.白话文解释多线程4.多线程存在的问题二、什么是高并发?1.高并发介绍2.如何提升系统的并发能力三、多线程和高并发总结 前言 本文主要是针对多线程和高并发的概念做了简单的描述,介绍了什么是多线程,什么是高并发,并且对多线程和高并发的关系做了比较描述。 一、什么是多线程? 1.多线程介绍 什么是多线程,首先看下百度百科对多线程的定义;多线程(multithreading) 阅读详情

线程池参数

线程池分为以下两种:
1、ThreadPoolExecutor
2、ForkJoinPool(分叉完了再汇总)
分解汇总的任务
用很少的线程可以执行很多的任务(子任务)ThreadPoolExecutor做不到先执行子任务
CPU密集型

ThreadPoolExecutor

线程池七个参数:
1、corePoolSize:核心线程数(线程池初始化线程数)
2、maximumPoolSize:最大线程数(可以从操作系统拿的线程数(可拿线程数=最大线程数-核心线程数))
3、KeepAliveTime 存活时间(如果可拿的那些线程超过存活时间了要归还给操作系统)
4、存活时间的单位
5、任务队列(阻塞队列)
6、线程工厂(默认DefaultThreadFactory)
7、拒绝策略 (在线程池达到最大线程数,且任务队列满)
JDK默认提供四种拒绝策略
Abort:抛异常
DisCard:扔掉,不抛异常
DiscardOldest:扔掉排队时间最久的
CallerRuns:调用者处理任务(哪个线程提交的任务哪个线程就去处理它)

说明:
线程池不允许使用Executors去创建,而是通过ThreadPoolExecutor的方式
Executors返回线程池对象的弊端如下:
FixedThreadPool和SingleThreadPool:
允许的请求队列的长度为Integer.Max_Value,可能会堆积大量的请求,从而导致OOM。
CachedThreadPool:
允许的创建线程数量为Integer.Max_Value,可能会创建大量的线程,从而导致OOM

拒绝策略测试代码如下:

 static class Task implements Runnable {
        private int i;

        public Task(int i) {
            this.i = i;
        }

        @Override
        public void run() {
            System.out.println(Thread.currentThread().getName() + " Task " + i);
            try {
                System.in.read();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

        @Override
        public String toString() {
            return "Task{" +
                    "i=" + i +
                    '}';
        }
    }

    public static void main(String[] args) {

        ThreadPoolExecutor tpe = new ThreadPoolExecutor(2, 4,
                60, TimeUnit.SECONDS,
                new ArrayBlockingQueue<Runnable>(4)/*TransferQueue*/ /*SynchronousQueue*/,
                Executors.defaultThreadFactory(),
                new ThreadPoolExecutor.DiscardOldestPolicy());

        for (int i = 0; i < 8; i++) {
            tpe.execute(new Task(i));
        }

        System.out.println(tpe.getQueue());

        tpe.execute(new Task(100));

        System.out.println(tpe.getQueue());

        tpe.shutdown();
    }

一般业务中自定义拒绝策略:
实现拒绝策略的接口,将消息保存下来(kafka,redis,mq,mysql)并对未处理任务做日志,当我们发现有大量任务未处理时则需要扩展机器了。

SingleThreadPool

Executors为线程池的工厂

SingleThreadPool顾名思义该线程池只有一个线程在运行,可以保证任务是顺序执行的。

   public static void main(String[] args) {
        ExecutorService service = Executors.newSingleThreadExecutor();
        for (int i = 0; i < 5; i++) {
            final int j = i;
            service.execute(() -> {

                System.out.println(j + " " + Thread.currentThread().getName());
            });
        }

    }

在这里插入图片描述
为什么要有单线程的线程池?
线程池是有任务队列的
能提供完整的生命周期管理
源码如下:

    public static ExecutorService newSingleThreadExecutor() {
        return new FinalizableDelegatedExecutorService
            (new ThreadPoolExecutor(1, 1,
                                    0L, TimeUnit.MILLISECONDS,
                                    new LinkedBlockingQueue<Runnable>()));
    }

CachedThreadPool(弹性线程池)

    public static ExecutorService newCachedThreadPool() {
        return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
                                      60L, TimeUnit.SECONDS,
                                      new SynchronousQueue<Runnable>());
    }

SynchronousQueue:是一个容量为空的队列,就是来一个任务必须得有一个线程去处理,否则提交任务得线程就阻塞在那里。

public static void main(String[] args) throws InterruptedException {
        ExecutorService service = Executors.newCachedThreadPool();
        System.out.println(service);
        for (int i = 0; i < 2; i++) {
            service.execute(() -> {
                try {
                    TimeUnit.MILLISECONDS.sleep(500);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println(Thread.currentThread().getName());
            });
        }
        System.out.println(service);

        TimeUnit.SECONDS.sleep(80);

        System.out.println(service);


    }

在这里插入图片描述

FixedThreadPool(固定多少个线程的线程池)

核心线程和最大线程数都是固定的,用的LinkedBlockingQueue
在这里插入图片描述
什么时候使用Fixed什么时候使用Cached?
任务量忽高忽低,保证任务不堆积Cached
任务来的比较平稳,估算了线程数量则用Fixed
但是阿里都不用,需要自己进行估算

应用代码如下:

public static void main(String[] args) throws InterruptedException, ExecutionException {
        long start = System.currentTimeMillis();
        getPrime(1, 200000);
        long end = System.currentTimeMillis();
        System.out.println(end - start);

        final int cpuCoreNum = 4;

        ExecutorService service = Executors.newFixedThreadPool(cpuCoreNum);

        MyTask t1 = new MyTask(1, 50000); //1-5 5-10 10-15 15-20
        MyTask t2 = new MyTask(50001, 100000);
        MyTask t3 = new MyTask(100001, 150000);
        MyTask t4 = new MyTask(150001, 200000);

        Future<List<Integer>> f1 = service.submit(t1);
        Future<List<Integer>> f2 = service.submit(t2);
        Future<List<Integer>> f3 = service.submit(t3);
        Future<List<Integer>> f4 = service.submit(t4);

        start = System.currentTimeMillis();
        f1.get();
        f2.get();
        f3.get();
        f4.get();
        end = System.currentTimeMillis();
        System.out.println(end - start);
    }

    static class MyTask implements Callable<List<Integer>> {
        int startPos, endPos;

        MyTask(int s, int e) {
            this.startPos = s;
            this.endPos = e;
        }

        @Override
        public List<Integer> call() throws Exception {
            List<Integer> r = getPrime(startPos, endPos);
            return r;
        }

    }

    static boolean isPrime(int num) {
        for (int i = 2; i <= num / 2; i++) {
            if (num % i == 0) return false;
        }
        return true;
    }

    static List<Integer> getPrime(int start, int end) {
        List<Integer> results = new ArrayList<>();
        for (int i = start; i <= end; i++) {
            if (isPrime(i)) results.add(i);
        }

        return results;
    }

ScheduledThreadPool(用来执行定时任务的线程池)

 public ScheduledThreadPoolExecutor(int corePoolSize) {
        super(corePoolSize, Integer.MAX_VALUE,
              DEFAULT_KEEPALIVE_MILLIS, MILLISECONDS,
              new DelayedWorkQueue());
    }

DelayedWorkQueue指定隔多长时间后运行

使用方式:

 public static void main(String[] args) {
        ScheduledExecutorService service = Executors.newScheduledThreadPool(4);
        service.scheduleAtFixedRate(() -> {
            try {
                TimeUnit.MILLISECONDS.sleep(new Random().nextInt(1000));
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println(Thread.currentThread().getName());
        }, 0, 500, TimeUnit.MILLISECONDS);
        // initialDelay第一个任务隔多少时间执行  period隔多少时间执行一次,
    }

通过scheduleAtFixedRate方法让任务每隔一段时间执行一次。

并发(concurrent)和并行对比(parallel)

并发是指任务提交,并行指任务执行

并行是并发的子集(并发是指多个任务同时涌向CPU,而并行则是多个CPU可以同时进行处理)

高并发与多线程关系与区别 一、什么是高并发 高并发(High Concurrency)是一种系统运行过程中遇到的一种“短时间内遇到大量操作请求”的情况,主要发生在web系统集中大量访问收到大量请求(例如:12306的抢票情况;天猫双十一活动)。该情况的发生会导致系统在这段时间内执行大量操作,例如对资源的请求、数据库的操作等。 二、高并发的处理指标 高并发相关常用的一些指标有:响应时间、吞吐量、每秒查询率QPS、并发用户数 1、响应时间(Response Time) 响应时间:系统对请求做出响应的时间。例如系统处... 阅读详情

相关推荐

一个线程池的设计

一个线程池的设计

Java并发编程(7)-ThreadPoolExecutor的饱和策略

文章目录一、ThreadPoolExecutor的饱和策略1.1、什么是饱和策略1.2、Abort策略1.3、.CallerRuns策略1.4、Discard策略1.5、DiscardOldest策略二、ThreadPoolExecutor的扩展方法 本文将介绍ThreadPoolExecutor的饱和策略以及ThreadPoolExecutor的扩展方法;当线程充满了ThreadPool的有...

BoringError的博客 2128

从零开始,用Cadence Virtuoso手把手仿真一个1.5V LDO(附完整电路与仿真脚本)

本文详细介绍了如何使用Cadence Virtuoso从零开始仿真一个1.5V LDO,包括环境准备、电路导入、Testbench构建、核心仿真类型分析以及高级调试技巧。通过完整的电路与仿真脚本,帮助读者掌握LDO设计与仿真的关键技术,提升电路设计能力。

weixin_31309419的博客 445

13、线程池

程序的运行,本质就是消耗系统资源,当我们频繁的创建和销毁线程时,会十分浪费系统资源,因此为了优化资源的使用,我们就有必要使用线程池的技术。 池化技术:实现分配好一定的资源,当有需要用时,就从分配好的资源中取出,用完后再归还; 1、线程池的优势 (1)降低资源消耗。通过重复利用已创建的线程降低线程创建和销毁造成的消耗。 (2)提高响应速度。当任务到达时,任务可以不需要等到线程创建就能立即执行。 (3)提高线程的可管理性。线程是稀缺资源,如果无限制的创建,不仅会消耗系统资源,还会降低系统的稳定性,使用线程

qq_49451343的博客 430

Lattice FPGA 开发工具Diamond使用流程总结——工具使用

本文介绍了一般的Diamond开发流程,包括工程创建、文件输入、IP使用、约束、管脚分配、和布线布局等流程

weixin_41895751的博客 2万+

Proteus一体化安装STC15库添加

Proteus一体化安装与STC15库添加指南 本文详细介绍了Proteus 8.9 SP2专业版的一体化安装流程和STC15系列单片机库文件的添加方法。安装过程简单快捷,无需破解,稳定性好。通过将两个库文件(Lib和LIB)复制到Proteus安装目录的DATA/LIBRARY文件夹中,即可实现STC15W4K32S4芯片的仿真功能。文中还提供了新建工程和器件放置的步骤说明,特别指出STC15W4K32S4芯片可兼容仿真其他STC15系列芯片,并附带下载链接获取资源。该教程适用于电子设计初学者和开发者。

#法外狂徒张三的博客 4万+

Java笔试面试题AI答之线程(15)

以上四种同步工具类各有特点,适用于不同的多线程同步场景。Semaphore适用于控制同时访问资源的线程数量,CountDownLatch适用于等待一组线程完成操作,CyclicBarrier适用于一组线程在继续执行前相互等待,而Exchanger则适用于两个线程之间的数据交换。这些工具类共同构成了Java多线程同步的强大机制。线程池任务饱和时的处理策略是线程池管理中的一个重要环节,需要根据具体的业务场景和需求进行选择和配置。

学无止境,止于至善 1218

使用Qt Creator调用eBUS SDK

在新界面,勾选左下角“ Show unreachable Network Devices",可以看到没有成功连接的网络相机,原因是IP地址配置错误。每个版本的OpenCV的依赖项的名字都不同,我这里是opencv_world490.lib与opencv_world490d.lib。函数,可以看到在这里是图像缓存区,能够对捕获的图像进行一些操作。在Visual Studio打开项目属性,在VC++目录这里,把Opencv的路径添加进去。这时,会自动跳转到mainwindow.cpp,生成该按钮对应的槽函数。

qq_35685051的博客 1288

从源码分析线程池(池化技术)的实现原理

线程池是一个非常重要的知识点,也是池化技术的一个典型应用,相信很多人都有使用线程池的经历,但是对于线程池的实现原理大家都了解吗?本篇文章我们将深入线程池源码来一探究竟。 线程池的起源 背景: 随着计算机硬件的升级换代,使我们的软件具备多线程执行任务的能力。当我们在进行多线程编程时,就需要创建线程,如果说程序并发很高的话,我们会创建大量的线程,而每个线程执行一个时间很短的任务就结束了,这样频繁创建线程,会极大的降低系统性能,增加服务器开销,因为创建线程和销毁线程都需要额外的消耗。 这时我们就可以...

weixin_45987961的博客 7051

ESP32-S3驱动雨滴传感器实战:从原理到ADC/GPIO双模式数据采集

本文详细介绍了ESP32-S3驱动雨滴传感器的实战教程,涵盖其工作原理及ADC/GPIO双模式数据采集方法。通过解析传感器利用水的导电性检测雨量的核心机制,提供了完整的硬件连接方案与软件驱动代码,包括模拟量(AO)的ADC读取和数字量(DO)的GPIO读取,并附有调试技巧,帮助开发者快速实现雨滴检测功能。

weixin_32005771的博客 154

量子密钥分发(QKD)原理、工程实现与实战部署全解析

密钥分发是信息安全的核心基础,它解决了通信双方如何安全共享秘密密钥的难题。传统方法依赖于数学问题的计算复杂性,而量子密钥分发(QKD)则基于量子力学原理,为密钥分发提供了信息论安全的物理保障。其核心价值在于,利用量子不可克隆定理和测量坍缩原理,使得任何窃听行为都会被合法通信方检测到,从而在理论上实现无条件安全的密钥协商。这项技术特别适用于对安全性要求极高的场景,如金融数据同步、政务专网和电力系统保护。本文聚焦于量子保密通信,深入剖析了以BB84协议为代表的QKD工作原理,并详细拆解了包含单光子探测、偏振编码

weixin_29324401的博客 346

java四种线程池的使用

参考:https://blog.youkuaiyun.com/w05980598/article/details/79425071 参考:https://blog.youkuaiyun.com/achuo/article/details/80623893 一、四种线程池 Java通过Executors提供四种线程池,分别为: 1、newSingleThreadExecutor 创建一个单线...

arjg30483的博客 472

嵌入式u-boot最全面试题及参考答案(5万字长文持续更新)

例如,在一个便携式设备中,U-Boot 在启动时初始化电源控制器,将输出电压设置为合适的值。命令是u-boot构建过程中用于配置u-boot选项的命令。在嵌入式系统中,启动画面(也称为启动Logo或Splash Screen)是展示给用户的第一印象,它可以包含公司的标志、产品的名称或其他相关信息。u-boot允许通过环境变量来进行配置,这使得开发者可以根据不同的硬件平台和项目需求灵活地调整u-boot的行为。写入操作可以是字节级别的,也可以是块级别的,具体取决于设备的性能和操作系统的需求。

大模型大数据攻城狮的专栏 997

全网最全的 Java 多线程与高并发实战体系化学习资料

多线程与高并发是Java开发的核心竞争力,需通过体系化学习+大量实战掌握。线程安全基础(synchronized、volatile、原子类)。线程池调优与并发工具(CountDownLatch、Semaphore)。分布式场景(分布式锁、限流、最终一致性)。实战项目(秒杀系统、分布式ID生成器)。结合本文资源,可逐步构建从理论到实战的完整知识体系,应对面试与实际开发挑战。每学一个知识点,编写对应代码示例(如线程池参数调优实验)。复现经典项目(秒杀系统、分布式ID生成器)。分阶段突破。

一叶之秋的博客 2565

YOLO26 网络结构逐模块解析:Backbone/Neck/Head

本文解析了YOLO26目标检测网络的架构设计,重点介绍其在Backbone、Neck和Head三个核心组件的创新优化。Backbone采用改进的CSP模块与轻量级注意力机制,提升特征提取效率;Neck使用改进的BiFPN结构实现高效多尺度特征融合;Head采用完全解耦设计简化回归流程。文章详细分析了各模块的技术演进、实现细节和设计思想,通过流程图和代码示例展示了YOLO26的整体架构和关键组件实现。该研究对模型优化、定制开发和硬件部署具有重要指导意义。

一键难忘的博客 1246

老版QQ原生表情gif动态

这是老版的QQ表情,不过全是动态的的,Windows照片查看器是不会动的,可以右击用浏览器打开查看,再说一遍是老版的,只是分享给宁愿用老版也要动态的人。

多线程与高并发整理总结【超全面】

我们先说一下为什么要讲多线程和高并发? 原因是,你想拿到一个更高的薪水,在面试的时候呈现出了两个方向的现象: 第一个上天 项目经验 高并发、缓存、大流量、大数据量的架构设计 第二个入地 各种基础算法,各种基础的数据结构 JVM OS线程、IO等内容 多线程和高并发,就是入地里面的内容。 一、基本概念 我们先从线程的基本概念开始,给大家复习一下。如果基础不太好,说什么是线程都不知道的,则需要花时间去补初级内容的课。 1. 什么是进程?什么是线程? Program app,比如QQ.exe

认知 行动 坚持 3018

Outlook Express 6 (OE6) for Win7/Win8/Win10

英文版 Outlook Express6.0, 兼容Win7/Win10/WinXP,解压就可用。

高并发与多线程的关系与区别

一、什么是高并发        高并发(High Concurrency)是一种系统运行过程中遇到的一种“短时间内遇到大量操作请求”的情况,主要发生在web系统集中大量访问收到大量请求(例如:12306的抢票情况;天猫双十一活动)。该情况的发生会导致系统在这段时间内执行大量操作,例如对资源的请求、数据库的操作等。 二、高并发的处理指标 高并发相关常用的一些指标有:响应时...

weixin_48358336的博客 3104

Devexpress16.2.6破解工具

Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具

ssm框架搭建

这个是一个在idea上成功跑起来的ssm框架项目,保存在这里方便以后使用直接下载

多线程与高并发

关键词: 线程,同步,单例,高并发,高访问,死锁 一、大规模并发带来的挑战 在过去的工作中,我曾经面对过5w每秒的高并发秒杀功能,在这个过程中,整个Web系统遇到了很多的问题和挑战。如果Web系统不做针对性的优化,会轻而易举地陷入到异常状态。我们现在一起来讨论下,优化的思路和方法哈。 1. 请求接口的合理设计 一个秒杀或者抢购页面,通常分为2个部分,一个是静态的HTML等内容,另一个就是参与...

ANGEL CITY 1857

什么是高并发与多线程?

线程 是程序执行的最小单元,是进程中的一个独立执行路径。一个进程可以包含多个线程,这些线程共享进程的资源(如内存、文件句柄等),但每个线程有自己的栈和程序计数器。多线程是 Java 编程中的一个重要特性,它允许程序同时执行多个任务,从而提高程序的效率和性能。Java 提供了丰富的 API 来支持多线程编程,包括 Thread 类、Runnable 接口、Executor 框架、MultiFutureThread等。优点是提高程序的效率、缺点是比较消耗CPU和内存。

qq_43380361的博客 963

详细介绍:多线程高并发

高并发与多线程的关系与区别 liuhuiteng 2019-03-09 21:30:41 13357 收藏 80 分类专栏: Java进阶 文章标签: 高并发 多线程 高并发指标 高并发解决方案 一、什么是高并发 高并发(High Concurrency)是一种系统运行过程中遇到的一种“短时间内遇到大量操作请求”的情况,主要发生在web系统集中大量访问收到大量请求(例如:12306的抢票情况;天猫双十一活动)。该情况的发生会导致系统在这段时间内执行大量操作,例如对资源的请求、数据库的操作等。 二、高并发

weixin_47043353的博客 3920

多线程与高并发编程(七)【线程池一】

多线程与高并发编程(七)【线程池一】一、线程池前置1. Executor接口 executor()2. ExecutorSevice接口,定义了很多线程池的生命周期的方法3. Callable接口(定义了call()),类似runnable,是一个任务,但是相比runnable中的run()多了个返回值。4. Future接口,承接ExecutorService方法中的返回值,是一个结果5. Fu...

qq_36268025的博客 810

[并发概念] 多线程与高并发

多线程的理解 什么是多线程 如果一个程序允许两个或者两个以上的线程,那么它便是多线程程序。多线程是指单个进程内允许多个线程。 任务分为资源独立任务和资源共享任务。独立任务不需要使用多线程;共享任务,会使用到进程共享资源,需要保证线程安全。 场景理解:房子与租客 假设有一套房子,住着我和我的几个室友,房子比喻进程,我和室友比喻线程。房子中有很多公共空间,例如厨房、客厅,每个人都可以到客厅来。厨房和客...

大唐雨夜的博客 1804

多线程和高并发的区别

“高并发和多线程”总是被被一起提起,给人的感觉好像他们相等,其实 高并发 不等于 多线程 多线程是完成任务的一种方法,高并发是系统运行的一种状态,通过多线程有助于系统承受高并发的状态的实现。 高并发是系统运行过程张遇到的一种“短时间内遇到大量的操作请求” 的情况,主要发生在web系统集中大量访问或者socket端口集中行收到大量请求(例如12306抢票;天猫双十一活动)。该情况...

qq_41002779的博客 6092

多线程高并发这一篇就够了不用再去别家了

  高伸缩性的并发编程是一种艺术,是成为高级程序员的必备知识点之一,最近总结了一下相关方面的知识。   借鉴过得博客有的我也不知道原文作业是谁 https://blog.youkuaiyun.com/qq_34337272/article/details/81072874 https://www.cnblogs.com/dolphin0520/p/3932921.html 一、线程 什么是线程? 线程是进...

qq_40388552的博客 7731

高并发与多线程的关系、区别、高并发的技术方案

什么是高并发? 高并发(High Concurrency)是一种系统运行过程中遇到的一种“短时间内遇到大量操作请求”的情况,主要发生在web系统集中大量访问收到大量请求(例如:12306的抢票情况;天猫双十一活动)。该情况的发生会导致系统在这段时间内执行大量操作,例如对资源的请求,数据库的操作等。 高并发的处理指标? 高并发相关常用的一些指标有: 1.响应时间(Response Time)...

weixin_43814458的博客 1584

Java多线程与高并发入门到精通(带视频讲解)

Java多线程与高并发入门到精通(带视频讲解)

闲余知道 1302
上一篇: 多线程与高并发学习七
下一篇: 多线程与高并发学习八
lsd&xql
博客等级 码龄8年 843粉丝 188原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值