JAVA--多线程
Java中的多线程是指在同一个Java虚拟机(JVM)中并发执行多个线程的能力。线程是程序执行的最小单元,Java提供了丰富的API来创建和管理线程。以下是Java中实现多线程的一些关键概念和方法:
-
Thread 类:Java提供了
Thread类来创建和管理线程。通过继承Thread类并重写其run()方法,可以定义线程执行的任务。 -
Runnable 接口:Java还提供了
Runnable接口,它包含一个run()方法。实现Runnable接口的类可以被传递给Thread类的构造器,从而创建一个新的线程。 -
创建线程:可以通过继承
Thread类或实现Runnable接口来创建线程。然后,通过调用start()方法启动线程。 -
生命周期:线程有几种状态,包括新建、就绪、运行、阻塞和死亡。线程状态的变化由线程的生命周期管理。
-
同步:当多个线程访问共享资源时,需要同步以避免数据不一致。Java提供了
synchronized关键字和ReentrantLock等同步机制。 -
线程池:Java提供了线程池(
ExecutorService)来管理线程的创建和销毁,提高资源利用率和执行效率。 -
中断:线程可以被中断,这是线程间通信的一种方式。通过调用线程的
interrupt()方法可以设置中断状态,而通过检查线程的isInterrupted()方法可以响应中断。 -
等待/通知机制:Java提供了
wait()、notify()和notifyAll()方法,允许线程在某些条件下等待,或在条件满足时被唤醒。 -
死锁:当多个线程相互等待对方释放资源时,可能会发生死锁。Java提供了工具和方法来检测和避免死锁。
-
并发集合:Java并发包(
java.util.concurrent)提供了线程安全的集合类,如ConcurrentHashMap、CopyOnWriteArrayList等。
下面是一个简单的Java多线程示例,演示了如何创建和启动线程:
// 使用Runnable接口创建线程
class Task implements Runnable {private int taskId;public Task(int id) {this.taskId = id;}@Overridepublic void run() {System.out.println("Task " + taskId + " is running by " + Thread.currentThread().getName());// 执行任务的代码}
}public class MultiThreadExample {public static void main(String[] args) {// 创建线程Thread thread1 = new Thread(new Task(1), "Thread-1");Thread thread2 = new Thread(new Task(2), "Thread-2");// 启动线程thread1.start();thread2.start();}
}
在这个示例中,我们定义了一个Task类实现了Runnable接口,并重写了run()方法来执行任务。然后在main方法中创建了两个线程,并通过调用它们的start()方法来启动它们。
Java多线程编程是一个复杂的话题,涉及到线程安全、性能优化、资源管理等多个方面。正确地使用多线程可以提高程序的性能和响应能力,但同时也需要小心处理线程间的交互和同步问题。
在Java中,实现线程间的同步和互斥主要依赖于同步机制,以下是一些常用的方法:
-
synchronized 关键字:
- 可以用来修饰方法或者代码块。
- 当一个线程访问一个对象的
synchronized方法或者同步代码块时,它会获得这个对象的锁。 - 其他线程必须等待锁释放后才能访问该对象的任何其他
synchronized方法或同步代码块。
-
wait() 和 notify() 方法:
wait()方法使当前线程等待,直到其他线程调用相同对象的notify()或notifyAll()方法。notify()唤醒在此对象监视器上等待的单个线程,而notifyAll()唤醒所有在此对象监视器上等待的线程。
-
Lock 接口和其实现类:
- Java并发API提供了
java.util.concurrent.locks.Lock接口和一些实现类,如ReentrantLock。 - 这些锁提供了与
synchronized关键字类似的功能,但提供了更多的灵活性,例如尝试非阻塞获取锁、可中断的锁获取、超时等待等。
- Java并发API提供了
-
volatile 关键字:
- 确保变量的更新对所有线程立即可见。
- 当一个线程修改了一个
volatile变量的值,新值会立即同步到主内存中,其他线程可以立即看到这个新值。
-
Atomic 类:
- Java并发API提供了一组原子类,如
AtomicInteger、AtomicLong等,它们利用CAS(Compare-And-Swap)操作来保证操作的原子性。
- Java并发API提供了一组原子类,如
-
Concurrent 集合:
java.util.concurrent包提供了线程安全的集合类,如ConcurrentHashMap、CopyOnWriteArrayList等,它们内部实现了同步机制。
-
CountDownLatch、CyclicBarrier、Semaphore 和 Exchanger:
- 这些是Java并发API提供的同步辅助类,用于控制多个线程之间的协调。
下面是一个使用synchronized关键字和wait()/notify()方法实现线程间同步的示例:
public class Counter {private int count = 0;public synchronized void increment() {count++;System.out.println("Count: " + count);// 当计数达到某个值时,通知等待的线程if (count >= 5) {notifyAll();}}public synchronized void waitForCount() throws InterruptedException {while (count < 5) {wait();}}public static void main(String[] args) {Counter counter = new Counter();Thread incrementer = new Thread(() -> {for (int i = 0; i < 10; i++) {counter.increment();}});Thread waiter = new Thread(() -> {try {counter.waitForCount();System.out.println("Count has reached 5 or more.");} catch (InterruptedException e) {e.printStackTrace();}});incrementer.start();waiter.start();}
}
在这个示例中,Counter类有两个同步方法:increment()和waitForCount()。increment()方法每次被调用时都会增加计数并打印当前计数。如果计数达到5或以上,它会调用notifyAll()来唤醒等待的线程。waitForCount()方法使用wait()来等待计数达到5。
请注意,使用同步机制时,需要小心避免死锁和性能问题。正确的同步策略取决于具体的应用场景和需求。
笔者小,中,大厂均有面试经验,目前正在从事全栈开发工作,坚持每日分享java全栈开发知识与相关的面试真题,希望能够给大家带来帮助,同大家共同进步。
相关文章:
JAVA--多线程
Java中的多线程是指在同一个Java虚拟机(JVM)中并发执行多个线程的能力。线程是程序执行的最小单元,Java提供了丰富的API来创建和管理线程。以下是Java中实现多线程的一些关键概念和方法: Thread 类:Java提供了Thread类…...
ADB-DROM
# 读硬件信息 adb shell "cat /sys/block/mmcblk0/device/name" # MT6767/MT6768/MT6769/MT6762/MT6765/MT6761... # 频率档位 # 固定频率 adb shell "echo 0 > /sys/devices/platform/10012000.dvfsrc/helio-dvfsrc/dvfsrc_force_vcore_dvfs_opp" # …...
mysql 之 explain
1. 查看表的创建字段以及索引情况 show create table user_recommend; 2. 创建索引的原则:列的值比较离散 像性别字段,只有男,女 或者其他;expose字段,只有1分发,0不可分发。就不适宜在这种字段上添加索引…...
CentOS迁移案例 | 保障轨道交通安全、发挥基础设施效能,麒麟信安操作系统支撑某市轨道交通畅行无忧
为缓解城市交通拥堵难题,某市轨道交通公司计划新建一条贯穿城市关键区域、沿路设立20座站点的轨道交通线路,并基于麒麟信安操作系统构建轨道交通信号系统。 轨道交通信号系统是列车核心控制系统,负责列车运行的自动化控制,及对整…...
获取操作系统的信息(Go语言)
在 Go 语言中,你可以使用 runtime 和 os 包来查看操作系统的信息。以下是一些常见的操作系统信息获取方法: 1. 获取操作系统类型和架构信息 Go 的 runtime 包提供了基本的操作系统和架构信息: package mainimport ("fmt""r…...
【论文阅读】HuatuoGPT-II, One-stage Training for Medical Adaption of LLMs
总体概要 本文深入探讨了一款专为医疗领域设计的大规模语言模型——HuatuoGPT-II的创新、性能与应用。HuatuoGPT-II采用统一的单阶段训练流程,将传统的继续预训练和监督微调整合,有效解决了医疗数据的异质性问题,包括语言、体裁和格式差异&a…...
Excel表列序号
题目 给定一个Excel表格中的列名称,返回其相应的列序号。 例如, A -> 1 B -> 2 C -> 3 ... Z -> 26 AA -> 27 AB -> 28 ...示例 1: 输入: "A" 输出: 1示例 2: 输入: "AB" 输出: 28示例 3: 输入: "ZY&…...
IOS 03 纯代码封装自定义View控件
本节将通过纯代码进行封装自定义View控件,以常用的设置页的item为例,实现UI效果如下: 1、创建SettingView继承自UIView import UIKitclass SettingView: UIView {} 2、重写 init() 和 required init?(coder: NSCoder) 方法 纯代码创建Set…...
比较结构加法及其逆运算
在行列可自由变换的平面上有等式 13(3a11)2*4a14a22*4a32*4a44*4a122*4a14 3a11在平面上可能得到6个不同的4点结构,这6个结构的比例为2:1:2:2:4:2. 现在从右向左算,计…...
44.【C语言】指针(重难点)(G)
目录 19.字符指针变量 *定义 *简单说明 *如果是字符串 *像数组一样指定访问常量字符串的字符 *练习 20.数组指针变量 *定义 *格式 *例子 问题1 问题2 *利用指针打印 21.二维数组传参的本质 *回顾 往期推荐 19.字符指针变量 *定义 指向字符的指针变量,用于存储字符…...
746. 使用最小花费爬楼梯-dp3
. - 力扣(LeetCode). - 备战技术面试?力扣提供海量技术面试资源,帮助你高效提升编程技能,轻松拿下世界 IT 名企 Dream Offer。https://leetcode.cn/problems/min-cost-climbing-stairs/description/从左向右填dp表 class Solutio…...
MPU6050详细介绍
一、MPU6050介绍 MPU6050是由三个陀螺仪和三个加速度传感器组成的6轴运动处理组件 内部主要结构:陀螺仪、加速度计、数字运动处理器DMP(Digital Motion Processor) MPU6050有两个IIC接口,第一IIC接口可作为主接口给单片机传输数…...
【分享】Excel的3个隐藏功能
我们在制作Excel表格的时候,有时候会包含一些敏感信息,为了确保这些数据的安全性,Excel提供了隐藏功能来保护工作表,下面小编分享3个Excel常用的隐藏功能,一起来看看如何设置吧! 功能一:隐藏部分…...
Linux中的chown指令
chown(change owner)命令在 Linux 和其他类 Unix 系统中用于更改文件或目录的用户和/或组所有权。 基本用法 chown [选项] 用户名[:组名] 文件或目录 参数说明 用户名:指定新的文件或目录的所有者 组名:可选,指定新…...
UCOSIII内存管理机制详解
目录 前言 1. 内存管理概述 2. 内存区域(存储区)和内存块 3. 存储区控制块(OS_MEM) 4. 内存管理函数 5. 内存碎片问题 6. 注意事项 7.代码实现 7.1创建内存区域 7.2申请内存 7.3释放内存 前言 UCOSIII(即Mi…...
Android12 显示框架之Transaction----client端
目录:Android显示终极宝典 在前面的章节中,应用通过createSurface()在surfaceflinger中创建了一层layer,紧接着要做的事情就是对这个layer设置一些属性(或者叫状态),常设置的属性有位置、大小、z-order等等…...
在Windows上使用FRP搭建内网穿透:
FRP服务器端配置(公网服务器) 下载FRP: 访问FRP的GitHub发布页面:https://github.com/fatedier/frp/releases下载对应系统架构的frp_<version>_linux_amd64.tar.gz(如果你的服务器是Linux系统)或者f…...
TypeError: Cannot read properties of undefined (reading ‘scrollIntoView‘)(已解决)
问题复现:眨眼睛使用vitevue3实现跳转dom功能时使用了scrollIntoView方法,在打包上传以后使用该功能报错 小友可能会陷入误区,以为是函数方法有问题,毕竟在开发时是没有问题的, 而实际上呢问题出在获取节点失败了 在这…...
【解决】Unity Inspector 视窗脚本中文乱码问题
开发平台:Unity 2020 编程平台:Visual Studio 2022 问题描述 开发过程中,为便利化快速审阅代码内容,通过 Unity Inspector 确认代码内容与逻辑。但对于默认安装的 Visual Studio 编程平台,保存的 UTF- 8 脚本文件在…...
使用 C/C++访问 MySQL
目录 准备工作 尝试链接 MySQL Client MySQL 接口介绍 准备工作 保证 MySQL 服务有效。下载MySQL开发包(可以在MySQL官网下载安装也可以在软件源安装) MySQL 开发包通常会包含一些特定的头文件和库文件。您可以检查以下常见的路径: /us…...
springboot 百货中心供应链管理系统小程序
一、前言 随着我国经济迅速发展,人们对手机的需求越来越大,各种手机软件也都在被广泛应用,但是对于手机进行数据信息管理,对于手机的各种软件也是备受用户的喜爱,百货中心供应链管理系统被用户普遍使用,为方…...
React hook之useRef
React useRef 详解 useRef 是 React 提供的一个 Hook,用于在函数组件中创建可变的引用对象。它在 React 开发中有多种重要用途,下面我将全面详细地介绍它的特性和用法。 基本概念 1. 创建 ref const refContainer useRef(initialValue);initialValu…...
Go 语言接口详解
Go 语言接口详解 核心概念 接口定义 在 Go 语言中,接口是一种抽象类型,它定义了一组方法的集合: // 定义接口 type Shape interface {Area() float64Perimeter() float64 } 接口实现 Go 接口的实现是隐式的: // 矩形结构体…...
Matlab | matlab常用命令总结
常用命令 一、 基础操作与环境二、 矩阵与数组操作(核心)三、 绘图与可视化四、 编程与控制流五、 符号计算 (Symbolic Math Toolbox)六、 文件与数据 I/O七、 常用函数类别重要提示这是一份 MATLAB 常用命令和功能的总结,涵盖了基础操作、矩阵运算、绘图、编程和文件处理等…...
select、poll、epoll 与 Reactor 模式
在高并发网络编程领域,高效处理大量连接和 I/O 事件是系统性能的关键。select、poll、epoll 作为 I/O 多路复用技术的代表,以及基于它们实现的 Reactor 模式,为开发者提供了强大的工具。本文将深入探讨这些技术的底层原理、优缺点。 一、I…...
SAP学习笔记 - 开发26 - 前端Fiori开发 OData V2 和 V4 的差异 (Deepseek整理)
上一章用到了V2 的概念,其实 Fiori当中还有 V4,咱们这一章来总结一下 V2 和 V4。 SAP学习笔记 - 开发25 - 前端Fiori开发 Remote OData Service(使用远端Odata服务),代理中间件(ui5-middleware-simpleproxy)-CSDN博客…...
保姆级教程:在无网络无显卡的Windows电脑的vscode本地部署deepseek
文章目录 1 前言2 部署流程2.1 准备工作2.2 Ollama2.2.1 使用有网络的电脑下载Ollama2.2.2 安装Ollama(有网络的电脑)2.2.3 安装Ollama(无网络的电脑)2.2.4 安装验证2.2.5 修改大模型安装位置2.2.6 下载Deepseek模型 2.3 将deepse…...
CRMEB 中 PHP 短信扩展开发:涵盖一号通、阿里云、腾讯云、创蓝
目前已有一号通短信、阿里云短信、腾讯云短信扩展 扩展入口文件 文件目录 crmeb\services\sms\Sms.php 默认驱动类型为:一号通 namespace crmeb\services\sms;use crmeb\basic\BaseManager; use crmeb\services\AccessTokenServeService; use crmeb\services\sms\…...
NPOI Excel用OLE对象的形式插入文件附件以及插入图片
static void Main(string[] args) {XlsWithObjData();Console.WriteLine("输出完成"); }static void XlsWithObjData() {// 创建工作簿和单元格,只有HSSFWorkbook,XSSFWorkbook不可以HSSFWorkbook workbook new HSSFWorkbook();HSSFSheet sheet (HSSFSheet)workboo…...
WPF八大法则:告别模态窗口卡顿
⚙️ 核心问题:阻塞式模态窗口的缺陷 原始代码中ShowDialog()会阻塞UI线程,导致后续逻辑无法执行: var result modalWindow.ShowDialog(); // 线程阻塞 ProcessResult(result); // 必须等待窗口关闭根本问题:…...
