深入理解Java多线程与线程池:提升程序性能的利器


✨✨谢谢大家捧场,祝屏幕前的小伙伴们每天都有好运相伴左右,一定要天天开心哦!✨✨ 
🎈🎈作者主页: 喔的嘛呀🎈🎈

目录

引言

一、实现多线程

1.1. 继承Thread类

1.2. 实现Runnable接口

1.3. 区别与选择

总结

二.线程池

创建线程池

FixedThreadPool(固定大小线程池)

CachedThreadPool(缓存线程池)

ScheduledThreadPool(定时任务线程池)

提交任务给线程池执行

关闭线程池

完整示例

总结

三、使用线程池提高程序性能

步骤一:创建线程池

步骤二:提交任务给线程池执行

步骤三:关闭线程池

总结

总结


引言

在Java中,多线程是一种重要的编程方式,可以提高程序的并发性和性能。本篇博客将详细介绍如何实现Java中的多线程,以及如何使用线程池来提高程序性能。

一、实现多线程

在Java中,实现多线程主要有两种方式:继承Thread类和实现Runnable接口。下面分别介绍这两种方式的实现方法。

1.1. 继承Thread类

继承Thread类并重写run方法来定义线程的执行逻辑。

class MyThread extends Thread {public void run() {System.out.println("Thread running");}
}public class Main {public static void main(String[] args) {MyThread thread = new MyThread();thread.start(); // 启动线程}
}

1.2. 实现Runnable接口

实现Runnable接口,并将其实例传递给Thread类的构造方法。

class MyRunnable implements Runnable {public void run() {System.out.println("Thread running");}
}public class Main {public static void main(String[] args) {Thread thread = new Thread(new MyRunnable());thread.start(); // 启动线程}
}

1.3. 区别与选择

  • 继承Thread类:简单直观,但限制了类的继承关系。
  • 实现Runnable接口:避免了单继承的局限性,更符合面向对象设计原则。

通常推荐使用实现Runnable接口的方式来实现多线程,因为它更灵活,可以更好地管理和维护线程。

总结

通过以上两种方式,可以实现Java中的多线程。选择合适的方式取决于具体的需求和项目架构,但一般来说,实现Runnable接口是更好的选择。

二.线程池

线程池是一种管理和复用线程的机制,可以减少线程创建和销毁的开销,提高程序性能。Java提供了Executors工厂类来创建不同类型的线程池。

创建线程池

Java提供了几种不同类型的线程池,常用的有FixedThreadPool、CachedThreadPool和ScheduledThreadPool。

FixedThreadPool(固定大小线程池)

ExecutorService executor = Executors.newFixedThreadPool(5); // 创建固定大小的线程池,可以容纳5个线程

CachedThreadPool(缓存线程池)

ExecutorService executor = Executors.newCachedThreadPool(); // 创建一个根据需求自动扩展的线程池

ScheduledThreadPool(定时任务线程池)

ScheduledExecutorService executor = Executors.newScheduledThreadPool(3); // 创建一个可以执行定时任务的线程池,可以容纳3个线程

提交任务给线程池执行

通过submit方法将任务提交给线程池执行。

executor.submit(new Runnable() {public void run() {System.out.println("Task running");}
});

关闭线程池

在程序结束时,需要手动关闭线程池以释放资源。

executor.shutdown(); // 等待所有任务执行完毕后关闭线程池

完整示例

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;public class ThreadPoolExample {public static void main(String[] args) {ExecutorService executor = Executors.newFixedThreadPool(5);for (int i = 0; i < 10; i++) {executor.submit(new Runnable() {public void run() {System.out.println("Task running");}});}executor.shutdown();}
}

总结

通过使用线程池,可以更加灵活地管理和复用线程,避免了频繁创建和销毁线程的开销,提高了程序的性能和效率。根据实际需求选择合适的线程池类型可以更好地满足程序的需求。

三、使用线程池提高程序性能

线程池是一种管理和复用线程的机制,可以减少线程创建和销毁的开销,提高程序性能。Java提供了Executors工厂类来创建不同类型的线程池,下面详细介绍如何使用线程池提高程序性能。

步骤一:创建线程池

使用Executors工厂类创建一个线程池。可以根据实际需求选择不同类型的线程池,如FixedThreadPool、CachedThreadPool等。

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;public class ThreadPoolExample {public static void main(String[] args) {// 创建一个固定大小为5的线程池ExecutorService executor = Executors.newFixedThreadPool(5);

步骤二:提交任务给线程池执行

将任务通过submit方法提交给线程池执行。

        // 提交任务给线程池执行for (int i = 0; i < 10; i++) {executor.submit(new Runnable() {public void run() {System.out.println("Task running");}});}

步骤三:关闭线程池

在程序执行完毕后,需要关闭线程池以释放资源。

executor.shutdown();

示例代码:

演示如何使用线程池处理一批耗时任务。假设我们有一批需要处理的数据列表,我们可以使用线程池来并发处理这些数据,提高处理效率。

import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;public class ThreadPoolTaskExample {public static void main(String[] args) {// 模拟需要处理的数据列表List<Integer> dataList = new ArrayList<>();Random random = new Random();for (int i = 0; i < 10; i++) {dataList.add(random.nextInt(100));}// 创建一个固定大小为3的线程池ExecutorService executor = Executors.newFixedThreadPool(3);// 提交处理任务给线程池执行for (Integer data : dataList) {executor.submit(new ProcessTask(data));}// 关闭线程池executor.shutdown();}// 处理任务类static class ProcessTask implements Runnable {private Integer data;public ProcessTask(Integer data) {this.data = data;}public void run() {// 模拟数据处理过程System.out.println("Processing data: " + data + " in thread: " + Thread.currentThread().getName());try {// 模拟数据处理耗时Thread.sleep(2000);} catch (InterruptedException e) {e.printStackTrace();}System.out.println("Data processed: " + data);}}
}

       在这个示例中,我们模拟了一个数据处理任务,通过线程池并发处理多个数据。线程池的大小为3,即最多同时处理3个数据,其他数据会等待空闲线程。这样可以有效地利用系统资源,提高处理效率。                

总结

通过使用线程池,可以有效地管理和复用线程,避免了频繁创建和销毁线程的开销,提高了程序的性能和效率。合理地选择线程池的大小和类型,可以更好地满足程序的需求,避免系统资源被耗尽。

总结

使用线程池可以提高程序的性能,主要体现在以下几个方面:

  1. 减少线程创建和销毁的开销:线程池可以复用线程,避免频繁创建和销毁线程的开销,提高了线程的利用率。

  2. 控制并发线程数量:线程池可以控制并发线程的数量,避免系统资源被耗尽,保证系统的稳定性和响应性。

  3. 提高任务处理效率:通过并发执行任务,可以加快任务处理的速度,提高程序的整体性能。

  4. 提高系统的响应速度:通过合理配置线程池的大小和类型,可以更好地响应用户的请求,提高系统的响应速度。

综上所述,使用线程池可以有效地提高程序的性能和效率,是多线程编程中的重要技术之一。

         

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

趣学前端 | Taro迁移完成之后,总结了一些踩坑经验

背景 四月份的时候&#xff0c;尝试将老的移动端项目改造成多端。因为老项目使用的React框架&#xff0c;综合考量&#xff0c;保障当前业务开发的进度同时&#xff0c;进行项目迁移&#xff0c;所以最后选择了Taro框架。迁移成本会低一些&#xff0c;上手快一些。 上个月&am…

js之原型链

在JavaScript中&#xff0c;原型链是一种用于实现继承和属性查找的机制。每个对象都有一个内部属性[[Prototype]]&#xff0c;这个属性指向创建该对象时使用的构造函数的“prototype"属性。对象的方法和属性定义在它的原型对象上。 1.原型&#xff08;Prototypes&#xf…

AIGC实战——GPT(Generative Pre-trained Transformer)

AIGC实战——GPT 0. 前言1. GPT 简介2. 葡萄酒评论数据集3. 注意力机制3.1 查询、键和值3.2 多头注意力3.3 因果掩码 4. Transformer4.1 Transformer 块4.2 位置编码 5. 训练GPT6. GPT 分析6.1 生成文本6.2 注意力分数 小结系列链接 0. 前言 注意力机制能够用于构建先进的文本…

mysql中 多表查询介绍

在 MySQL 中&#xff0c;多表查询是 SQL 语句的重要组成部分&#xff0c;用于从两个或多个表中检索数据。多表查询可以帮助我们更灵活地处理复杂的数据关系&#xff0c;并从中获取所需的信息。以下是 MySQL 中常见的多表查询及其特点、区别和应用场景。 常见多表查询 1. **内连…

java中几种对象存储(文件存储)中间件的介绍

一、前言 在博主得到系统中使用的对象存储主要有OSS&#xff08;阿里云的对象存储&#xff09; COS&#xff08;腾讯云的对象存储&#xff09;OBS&#xff08;华为云的对象存储&#xff09;还有就是MinIO 这些玩意。其实这种东西大差不差&#xff0c;几乎实现方式都是一样&…

【JAVA】CSS2:样式、选择器、伪类、颜色、字体、边框、列表、背景、盒子、布局、浮动

本文介绍了CSS样式、选择器、伪类、像素、颜色、字体、边框、列表、表格属性、背景、盒子、布局与浮动 1.样式 1.1 行内样式 <h1 style"color: aqua;font-size: large;">123</h1> 1.2 内部样式 <style>h1{color: red;font: 100;}</style>…

从16-bit 到 1.58-bit :大模型内存效率和准确性之间的最佳权衡

通过量化可以减少大型语言模型的大小&#xff0c;但是量化是不准确的&#xff0c;因为它在过程中丢失了信息。通常较大的llm可以在精度损失很小的情况下量化到较低的精度&#xff0c;而较小的llm则很难精确量化。 什么时候使用一个小的LLM比量化一个大的LLM更好? 在本文中&a…

关于比特币的AI对话

【ChatGPT】 比特币源码开源吗&#xff1f; 是的&#xff0c;比特币的源码是开源的。比特币项目是在MIT许可证下发布的&#xff0c;这意味着任何人都可以查看、修改、贡献和分发代码。比特币的源码托管在GitHub上&#xff0c;可以通过下面的链接进行访问&#xff1a; https://g…

13.【蓝桥杯】-ing 移除链表元素 简单题

一、题目 给你一个链表的头节点 head 和一个整数 val &#xff0c;请你删除链表中所有满足 Node.val val 的节点&#xff0c;并返回 新的头节点 。 示例 1&#xff1a; 输入&#xff1a;head [1,2,6,3,4,5,6], val 6 输出&#xff1a;[1,2,3,4,5]示例 2&#xff1a; 输入&…

【深度学习笔记】优化算法——学习率调度器

学习率调度器 &#x1f3f7;sec_scheduler 到目前为止&#xff0c;我们主要关注如何更新权重向量的优化算法&#xff0c;而不是它们的更新速率。 然而&#xff0c;调整学习率通常与实际算法同样重要&#xff0c;有如下几方面需要考虑&#xff1a; 首先&#xff0c;学习率的大…

2024-03-10 c++

&#x1f338; MFC下拉框控件 | Combo Box eg 计算器 1。新建MFC项目&#xff08;基于对话框、静态库&#xff09; 2。添加控件&#xff0c;删除初始的3个多余控件 加3个edit control 加1个combo box&#xff0c;属性sort改为false&#xff0c;data为 ;-;;;% 加1个static text…

不同路径 不同路径 II 整数拆分

62.不同路径 力扣题目链接(opens new window) 一个机器人位于一个 m x n 网格的左上角 &#xff08;起始点在下图中标记为 “Start” &#xff09;。 机器人每次只能向下或者向右移动一步。机器人试图达到网格的右下角&#xff08;在下图中标记为 “Finish” &#xff09;。…