单体应用提高性能和高并发处理-合理使用多核处理
合理使用多核处理能力是提升单体应用性能和处理高并发能力的重要手段。以下是关于如何合理利用多核处理器的详细讲解,包括多线程编程、线程池的使用、并行计算、以及如何避免常见的性能陷阱。
1. 多线程编程
多线程编程是利用多核处理器的直接方式。每个线程可以在不同的核心上并行执行,从而提高应用程序的执行效率。
知识点
- 线程模型:Java中,线程通过
Thread类或实现Runnable接口来创建。通过启动多个线程,应用程序可以在多个核心上并行运行。 - CPU密集型 vs I/O密集型任务:对于CPU密集型任务(如计算密集型操作),应该尽可能充分利用CPU核心。对于I/O密集型任务,线程的数量可以适度增加,以在等待I/O操作时切换到其他任务。
实例:
public class MultiThreadExample {public static void main(String[] args) {int numThreads = Runtime.getRuntime().availableProcessors(); // 获取可用的核心数for (int i = 0; i < numThreads; i++) {new Thread(new Task()).start(); // 启动多个线程}}
}class Task implements Runnable {@Overridepublic void run() {// 模拟CPU密集型任务long sum = 0;for (int i = 0; i < 1000000000; i++) {sum += i;}System.out.println(Thread.currentThread().getName() + " 完成任务,结果: " + sum);}
}
在这个例子中,根据可用的CPU核心数创建了多个线程来执行任务。每个线程都可以在不同的核心上运行,从而提高并行计算能力。
2. 使用线程池(Thread Pool)
线程池管理一组可重用的线程,避免频繁创建和销毁线程的开销,适合处理大量并发任务。
知识点
- 固定大小线程池(Fixed Thread Pool):创建一个固定数量的线程池,适合已知数量的并发任务。
- 缓存线程池(Cached Thread Pool):根据需求动态调整线程池大小,适合任务数量不确定的场景。
- Fork/Join框架:适用于递归分治算法,在多核环境下进行高效的并行计算。
实例:
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;public class ThreadPoolExample {public static void main(String[] args) {int numThreads = Runtime.getRuntime().availableProcessors();ExecutorService executor = Executors.newFixedThreadPool(numThreads); // 创建固定大小的线程池for (int i = 0; i < numThreads; i++) {executor.submit(new Task()); // 提交任务到线程池}executor.shutdown(); // 关闭线程池}
}class Task implements Runnable {@Overridepublic void run() {long sum = 0;for (int i = 0; i < 1000000000; i++) {sum += i;}System.out.println(Thread.currentThread().getName() + " 完成任务,结果: " + sum);}
}
通过使用线程池,避免了频繁创建和销毁线程的开销,提高了资源的利用率。
3. 并行计算(Parallel Computing)
并行计算是将一个大任务分解为多个子任务,并行在多个核心上执行。Java提供了Fork/Join框架来简化并行任务的管理。
知识点
- Fork/Join框架:用于将任务分解(Fork)成更小的子任务,然后并行执行,并在所有子任务完成后将结果合并(Join)。
RecursiveTask:适用于需要返回结果的并行任务。RecursiveAction:适用于不需要返回结果的并行任务。
实例:
import java.util.concurrent.RecursiveTask;
import java.util.concurrent.ForkJoinPool;public class ParallelExample extends RecursiveTask<Long> {private static final int THRESHOLD = 10000;private long start;private long end;public ParallelExample(long start, long end) {this.start = start;this.end = end;}@Overrideprotected Long compute() {if (end - start <= THRESHOLD) {long sum = 0;for (long i = start; i <= end; i++) {sum += i;}return sum;} else {long mid = (start + end) / 2;ParallelExample leftTask = new ParallelExample(start, mid);ParallelExample rightTask = new ParallelExample(mid + 1, end);leftTask.fork(); // 异步执行左边任务long rightResult = rightTask.compute(); // 同步执行右边任务long leftResult = leftTask.join(); // 获取左边任务结果return leftResult + rightResult;}}public static void main(String[] args) {ForkJoinPool forkJoinPool = new ForkJoinPool();ParallelExample task = new ParallelExample(1, 100000000L);long result = forkJoinPool.invoke(task);System.out.println("并行计算结果: " + result);}
}
Fork/Join框架将大任务分解为多个子任务并行执行,从而充分利用多核处理能力。
4. 合理设置线程数
合理设置线程数是多核处理的关键。过多的线程会导致上下文切换开销过大,过少的线程则不能充分利用CPU。
知识点
- CPU密集型任务:通常线程数设置为核心数,最大化利用每个核心。
- I/O密集型任务:线程数可以大于核心数,以在等待I/O操作时进行线程切换。
- 自适应线程池:可以根据系统负载动态调整线程池的大小。
实例:
public class OptimalThreadNumberExample {public static void main(String[] args) {int numThreads = Runtime.getRuntime().availableProcessors();System.out.println("推荐线程数(CPU密集型任务): " + numThreads);int ioBoundThreads = numThreads * 2; // I/O密集型任务时,线程数可以设置为核心数的2倍System.out.println("推荐线程数(I/O密集型任务): " + ioBoundThreads);}
}
此代码展示了根据任务类型推荐的线程数设置,帮助在不同场景下合理利用多核资源。
5. 避免共享资源竞争
多线程编程中,避免不同线程之间的资源争用,可以减少锁竞争,从而提高性能。
知识点
- 线程局部变量(ThreadLocal):为每个线程分配独立的变量,避免资源共享。
- 细粒度锁:尽量缩小锁的范围和粒度,减少线程竞争的机会。
实例:
public class ThreadLocalExample {private static ThreadLocal<Integer> threadLocalCounter = ThreadLocal.withInitial(() -> 0);public static void main(String[] args) {int numThreads = Runtime.getRuntime().availableProcessors();for (int i = 0; i < numThreads; i++) {new Thread(() -> {int counter = threadLocalCounter.get();counter++;threadLocalCounter.set(counter);System.out.println(Thread.currentThread().getName() + " 计数器值: " + threadLocalCounter.get());}).start();}}
}
使用ThreadLocal,每个线程都有独立的计数器,避免了对共享资源的竞争。
总结
合理使用多核处理能力可以显著提高单体应用的性能和高并发处理能力。以下是关键点:
- 多线程编程:利用多线程并行处理任务,充分利用多核资源。
- 线程池:使用线程池管理线程,减少创建和销毁线程的开销。
- 并行计算:将任务分解为子任务并行执行,使用
Fork/Join框架优化复杂计算。 - 合理设置线程数:根据任务类型设置合适的线程数,避免上下文切换和资源浪费。
- 避免共享资源竞争:通过
ThreadLocal和细粒度锁等技术减少线程间的资源争用。
通过这些策略,可以充分发挥多核处理器的优势,提升单体应用在高并发环境下的性能。
相关文章:
单体应用提高性能和高并发处理-合理使用多核处理
合理使用多核处理能力是提升单体应用性能和处理高并发能力的重要手段。以下是关于如何合理利用多核处理器的详细讲解,包括多线程编程、线程池的使用、并行计算、以及如何避免常见的性能陷阱。 1. 多线程编程 多线程编程是利用多核处理器的直接方式。每个线程可以在…...
基于STM32/GD32的双CAN、一路485开发板
双CAN开发板 双CAN、一路485开发板的设计开发板配置器件选型CAN设计硬件设计软件设计 485设计硬件设计软件设计 其他设计LED硬件按键硬件 PCB板子和实物图开发板测试视频其他资料 双CAN、一路485开发板的设计 最近工作经常会出现一些小问题。就想设计一款带CAN的开发板用来测试…...
快排/堆排/归并/冒泡/
常见的内排序算法 插入排序 直接插入排序 原理:相当于扑克牌变成有序,先拿第一张,把他调节成有序,再拿第二张,与第一张相比找到第二张的位置,再继续拿第三张,以此类推。 void InsertSort(in…...
React基础教程(08):state体验
文章目录 7、state再体验7.1 异步更新状态7.2 同步更新状态方式17.3 同步更新状态方式27.4 betterScroll7.5 列表案例7、state再体验 7.1 异步更新状态 完整代码 import React from "react";export default class App extends React.Component{state = {count:1,}…...
Win10 创建新的桌面2,并实现桌面切换
1. Win10 创建新的桌面2 Win - Tab 2. Win10 桌面切换 Ctrl - Win - ←/→ 我们下期见,拜拜!...
MySQL数据库介绍及基础操作
目录: 一.数据库介绍 二.数据库分类 三. 数据库的操作 四. 常用数据类型 五. 表的操作 一.数据库介绍 1.文件保存数据有以下几个缺点: 1.1文件的安全性问题 1.2文件不利于数据查询和管理 1.3文件不利于存储海量数据 1.4文件在程序中控制不方便 为了解决上述问题&…...
【C语言篇】C语言常考及易错题整理DAY2
文章目录 C语言常考及易错题整理选择题编程题至少是其他数字两倍的最大数两个数组的交集图片整理寻找数组的中心下标多数元素除自身以外数组的乘积不使用加减乘除求两个数的加法 C语言常考及易错题整理 选择题 下列 for 循环的次数为( ) for(int i 0…...
javase入门
最近在学习大数据,学到flume拦截器的时候发现自定义拦截器需要使用java编写,现在开始学一些java入门的东西. 一. java相关组成 path环境变量: 环境变量用于记住程序路径,方便在命令行窗口任意目录启动程序. 二 java中的变量 变量要先定义在使用. int age 15 定义变量要定义其…...
Wireshark显示过滤器大全:快速定位网络流量中的关键数据包
文章目录 一、简介二、wireshark中的逻辑运算符三、过滤示例集合3.1 过滤指定日期和时间3.2 过滤指定协议3.2.1 例:仅显示SMTP(端口 25)和ICMP流量:3.2.2 例如:Windows 客户端 - DC 交换 3.3 过滤指定网段(…...
OOP笔记4----抽象类、接口、枚举
抽象类 简介 父类可以封装不同子类的共同特征或者共同行为.而有的时候,父类中封装的方法无法具体完成子类中需要的逻辑,因此我们可以将此方法设计成抽象方法,即使用关键字abstract进行修饰。而有抽象方法的类,也必须使用abstract…...
MySQL面试题全解析:准备面试所需的关键知识点和实战经验
MySQL有哪几种数据存储引擎?有什么区别? MySQL支持多种数据存储引擎,其中最常见的是MyISAM和InnoDB引擎。可以通过使用"show engines"命令查看MySQL支持的存储引擎。 存储方式:MyISAM引擎将数据和索引分别存储在两个不…...
01_Electron 跨平台桌面应用开发介绍
Electron 跨平台桌面应用开发介绍 一、Electron 的介绍二、关于 NW.js 和 Electron 介绍三、搭建 Electron 的环境1、准备工作:2、安装 electron 环境3、查看 electron 的版本,electron -v 一、Electron 的介绍 Electron 是由 Github 开发的一个跨平台的…...
【C语言-扫雷游戏】mineweeper【未完成】
编程小白如何成为大神?大学新生的最佳入门攻略 编程已成为当代大学生的必备技能,但面对众多编程语言和学习资源,新生们常常感到迷茫。如何选择适合自己的编程语言?如何制定有效的学习计划?如何避免常见的学习陷阱&…...
psychopy stroop 实验设计
斯特鲁stroop实验就是色词一致/不一致实验。 设计步骤如下: 1. 先去设置中将Input改为PsychToolbox, 2. 然后左上角File-New新建一个 3. 右键trial,rename改名 改成自己想要的名字即可,比如欢迎界面welcome。 4. 接下来添加提示语…...
c++精品小游戏(无错畅玩版)
一、俄罗斯方块 #include <stdio.h> #include <string.h> #include <stdlib.h> #include <time.h> #include <conio.h> #include <windows.h>#ifdef _MSC_VER // M$的编译器要给予特殊照顾 #if _MSC_VER < 1200 // VC6及以下版本 #err…...
应急响应-主机安全之系统及进程排查相关命令(Linux操作系统-初级篇)
目录 概述lscpu-显示有关CPU架构的信息uname-查看系统信息lsmod-输出加载的所有模块lastb-输出最后登录失败的用户last-展示用户最近登录信息lastlog-展示所有用户最后的登录时间systemctl-系统服务,开机自启排查crontab-计划任务选项 history-查看历史命令选项常用…...
java中RSA分段加解密及Data must not be longer than异常处理
谈到RSA非对称加密,作为开发的我们第一想到的是安全,几乎不会被破解,以及公钥加密,私钥解密这些。在Java代码中,我们常使用一些现成的工具类如hutool中提供的工具类、网上在线的或者博客上的RSAUtils工具类来实现公钥私…...
MySQL数据分析进阶(十二)设计数据库——PART3
※食用指南:文章内容为‘CodeWithMosh’SQL进阶教程系列学习笔记,笔记整理比较粗糙,主要目的自存为主,记录完整的学习过程。(图片超级多,慎看!) 【中字】SQL进阶教程 | 史上最易懂S…...
Kubernetes-1.22.0 可视化部署
目录 Kubeadm方式部署3master,2work集群(Kubernetes-1.22.0)-CSDN博客 1. 官方Dashboard 2. Kuboard 部署 3. Rainbond 部署 4. Kubesphere 部署 1. 官方Dashboard kubectl apply -f https://kuboard.cn/install-script/k8s-dashboard/v2…...
在 vue3 中动态路由问题记录
第一种 如果这样子的话需要加上 /* vite-ignore / ,但是在这样用这行部署服务器上跳转会有问题 component: () > import(/ vite-ignore */ ../views/ e.component .vue) 第二种 // 解决跳转问题const modeules imporet.meta.glob(/views/**/**.vue)component: modules…...
19c补丁后oracle属主变化,导致不能识别磁盘组
补丁后服务器重启,数据库再次无法启动 ORA01017: invalid username/password; logon denied Oracle 19c 在打上 19.23 或以上补丁版本后,存在与用户组权限相关的问题。具体表现为,Oracle 实例的运行用户(oracle)和集…...
业务系统对接大模型的基础方案:架构设计与关键步骤
业务系统对接大模型:架构设计与关键步骤 在当今数字化转型的浪潮中,大语言模型(LLM)已成为企业提升业务效率和创新能力的关键技术之一。将大模型集成到业务系统中,不仅可以优化用户体验,还能为业务决策提供…...
k8s从入门到放弃之Ingress七层负载
k8s从入门到放弃之Ingress七层负载 在Kubernetes(简称K8s)中,Ingress是一个API对象,它允许你定义如何从集群外部访问集群内部的服务。Ingress可以提供负载均衡、SSL终结和基于名称的虚拟主机等功能。通过Ingress,你可…...
2025年能源电力系统与流体力学国际会议 (EPSFD 2025)
2025年能源电力系统与流体力学国际会议(EPSFD 2025)将于本年度在美丽的杭州盛大召开。作为全球能源、电力系统以及流体力学领域的顶级盛会,EPSFD 2025旨在为来自世界各地的科学家、工程师和研究人员提供一个展示最新研究成果、分享实践经验及…...
VTK如何让部分单位不可见
最近遇到一个需求,需要让一个vtkDataSet中的部分单元不可见,查阅了一些资料大概有以下几种方式 1.通过颜色映射表来进行,是最正规的做法 vtkNew<vtkLookupTable> lut; //值为0不显示,主要是最后一个参数,透明度…...
Bean 作用域有哪些?如何答出技术深度?
导语: Spring 面试绕不开 Bean 的作用域问题,这是面试官考察候选人对 Spring 框架理解深度的常见方式。本文将围绕“Spring 中的 Bean 作用域”展开,结合典型面试题及实战场景,帮你厘清重点,打破模板式回答,…...
Element-Plus:popconfirm与tooltip一起使用不生效?
你们好,我是金金金。 场景 我正在使用Element-plus组件库当中的el-popconfirm和el-tooltip,产品要求是两个需要结合一起使用,也就是鼠标悬浮上去有提示文字,并且点击之后需要出现气泡确认框 代码 <el-popconfirm title"是…...
Python爬虫(四):PyQuery 框架
PyQuery 框架详解与对比 BeautifulSoup 第一部分:PyQuery 框架介绍 1. PyQuery 是什么? PyQuery 是一个 Python 的 HTML/XML 解析库,它采用了 jQuery 的语法风格,让开发者能够用类似前端 jQuery 的方式处理文档解析。它的核心特…...
dvwa11——XSS(Reflected)
LOW 分析源码:无过滤 和上一关一样,这一关在输入框内输入,成功回显 <script>alert(relee);</script> MEDIUM 分析源码,是把<script>替换成了空格,但没有禁用大写 改大写即可,注意函数…...
MAZANOKE结合内网穿透技术实现跨地域图像优化服务的远程访问过程
文章目录 前言1. 关于MAZANOKE2. Docker部署3. 简单使用MAZANOKE4. 安装cpolar内网穿透5. 配置公网地址6. 配置固定公网地址总结 前言 在数字世界高速发展的今天,您是否察觉到那些静默增长的视觉数据正在悄然蚕食存储空间?随着影像记录成为日常习惯&…...
