并发,多线程,同步,线程池的使用

Java学习笔记(十八):实现多线程、线程同步、阻塞队列基本使用、线程池、多线程综合练习、原子性、并发工具类 概述生产者消费者模式是一个十分经典的多线程协作的模式,弄懂生产者消费者问题能够让我们对多线程编程的理解更加深刻。所谓生产者消费者问题,实际上主要是包含了两类线程:​ 一类是生产者线程用于生产数据​ 一类是消费者线程用于消费数据为了解耦生产者和消费者的关系,通常会采用共享的数据区域,就像是一个仓库生产者生产数据之后直接放置在共享数据区中,并不需要关心消费者的行为消费者只需要从共享数据区中去获取数据,并不需要关心生产者的行为Object类的等待和唤醒方法方法名说明。 阅读详情

并发与并行

并发:指的是两个事件或多个事件在同一时间段内发生。

并行:指的是两个事件或多个事件在同一时间点发生。

进程与线程

进程:是指一个内存中运行的应用程序,每个进程都有一个独立的内存空间,一个应用程序可以同时运行多个进程;进程也是程序的一次执行过程,是系统运行程序的基本单位;系统运行一个程序即是一个进程从创建,运行到消亡的过程。

线程:线程是进程中的一个执行单元,负责当前进程中程序的执行,一个进程中至少有一个线程。一个进程中是可以有多个线程的,这个应用程序也可以称为多线程程序。

(程序运行后至少有一个进程,一个进程中可以包含多个线程。)

线程的调度

分时调度:是指所有线程轮流使用CPU的使用权,平均分配每个线程占用CPU的时间。

抢占式调度:是指优先让优先级高的线程使用CPU,如果线程的优先级相同,那么会随机选择一个线程(线程随机性),java使用的为抢占式调度。

主线程(main线程)

主线程:执行主方法的线程。

单线程程序:java程序中只有一个线程,执行从main方法开始,从上到下依次执行。

单线程程序的弊端:主线程中出现异常,后续代码不会继续执行。

多线程原理

单线程程序执行时,只在一个栈空间内入栈出栈,所以发生异常后,后续代码不再执行。

而多线程程序执行时,每调用start()方法一次,就新开辟一个栈空间,这个栈空间和main方法的栈空间互不干扰,优先级相同时cpu随机选择一个线程执行。

创建多线程程序的方式:

继承Thread类

该类存在于java.lang包中。

实现步骤:
1.创建一个Thread类的子类;
2.在Thread类的子类中重写Thread类中的run()方法,设置线程任务;
3.创建Thread类的子类的对象;
4.调用Thread类中的方法start()方法,开启新的线程,执行run()方法。

注意:
1.执行start()方法后,jvm调用该线程的run方法,两个线程并发运行,一个是main线程,一个是执行run方法后新创建的线程。
2.多次启动一个线程是非法的,特别是当线程已经结束执行后,不能再重新启动。
3.java程序属于抢占式调度,哪个线程的优先级高,哪个线程优先执行,同一个优先级,随机选择一个执行。
4.可以通过Thread对象调用setPriority()方法设置线程的优先级。参数范围为1-9,参数越大优先级越高。

实现Runnable接口

推荐使用该方法。
该接口存在于java.lang包中。

实现步骤:
1.创建一个Runnable接口的实现类;
2.实现类重写Runnable接口的抽象方法run(),设置线程的任务;
3.创建一个Runnable接口的实现类对象;
4.创建Thread类对象,把Runnable接口的实现类对象作为参数传递给Thread类的构造方法;
5.调用Thread类的start方法,开启新线程。

两种方法的区别

1.使用继承Thread类的方法有局限性,即java的单继承。如果继承了Thread类,则后续无法继承其他类。
但是如果采用实现Runnable接口的方法,则可以避免该局限性,实现接口的同时还可以继承其他类。

2.实现Runnable接口的方法,将设置线程任务和开启新线程进行了分离,即在重写接口的run方法时设置线程任务,对Thread类构造函数传参和执行start方法时开启新线程。

线程安全问题

多线程程序访问了共享的数据,会产生线程安全问题。

线程安全问题产生的原理

多个线程同时开始执行时,如果访问同一个共享的资源,同时修改数据,就会出现预料之外的效果。所以我们要使一个线程在访问共享资源时,无论是否进入阻塞状态,释放cpu资源与否,其他线程都等待,已解决线程安全问题。

解决线程安全问题

同步代码块

语法:
synchronized(锁对象){
可能会出现安全问题的代码(访问了共享数据的代码)
}

注意:
1.代码块中的锁对象,可以使用任意的对象
2.必须保证多个线程使用的锁对象是同一个
3.锁对象作用:把同步代码块锁住,只让一个线程在同步代码块中执行。

同步方法

语法:
修饰符 synchronized 返回值类型 方法名(参数列表){
可能产生线程安全问题的代码
}

或

修饰符 返回值类型 方法名(参数列表){
synchronized(锁对象){
可能产生线程安全问题的代码
}
}

静态同步方法

语法:
修饰符 static synchronized 返回值类型 方法名(参数列表){
可能产生线程安全问题的代码
}

或

修饰符 static 返回值类型 方法名(参数列表){
synchronized(锁对象){
可能产生线程安全问题的代码
}
}

注意:
1.锁对象是谁?
对于非静态方法,锁对象是this。
对于静态方法,因为this是对象创建后才存在,所以锁对象是(类名.class)。

使用Lock接口

该接口存在于java.util.concurrent包中。

Lock接口提供了比synchronized方法和语句更广泛先进的锁操作。

接口中常用方法:
1.void lock() //获取锁
2.void unlock() //释放锁

使用步骤:
1.导包;
2.在成员位置创建一个ReentrantLock对象(也可以使用多态写法);
3.在可能会出现安全问题的代码之前通过对象调用Lock接口中的方法lock()获取锁。
4.在可能会出现安全问题的代码之后通过对象调用Lock接口中的方法unlock()释放锁。
5.如果有异常可以结合try-catch-finally语句,将释放锁语句放在finally代码块中,可以提高程序效率。

线程池的使用

线程结束后无法重新开启,使用线程池可以达到线程复用的效果。

线程池工厂类:java.util.concurrent.Executors:用来生成线程池

该类中的静态方法:
static ExecutorService newFixedThreadPool(int nThreads) 创建一个可重用固定线程数的线程池。
参数:int nThreads:创建线程池中包含的线程数量
返回值:ExecutorService接口的实现类对象,可以使用ExecutorService接口接收

使用步骤:
1.使用线程池的工厂类Executors里提供的静态方法newFixedThreadPool生产一个指定线程数量的线程池的接口ExecutorService。
2.创建一个Runnable接口的实现类,重写run方法,设置线程任务。
3.调用ExecutorService接口中的方法submit,参数传递这个实现类,开启线程,执行run方法。
//4.调用ExecutorService接口中的方法shutdown销毁线程池。

31、Java并发编程:线程池、数据同步与性能考量 本文深入探讨了Java并发编程中的核心概念和技术,包括线程池的创建与使用、数据同步机制以及性能优化的策略。通过合理使用线程池,可以提高并发性能;通过原子类、同步块和同步方法,可以保护共享数据的线程安全;同时,也分析了同步带来的性能成本和优化建议。文章还提供了多线程文件处理的综合示例,帮助读者更好地理解和应用并发编程技术。 阅读详情

相关推荐

【知识点总结】电机学——原理部分

大家好,由于院校地区存在疫情没法返校,再结合当下形式,去各地旅游放松可能不是一个好的决定,o(╥﹏╥)o,期待已久的旅行就先放一边吧,但也不能闲着,既然无事,那不如继续我的总结,本次总结的内容是电机学,自九推以后我越来越明白电机学的重要性……呜呜呜~~实在太重要了,几乎所有与专业复试有关的题目都会涉及电机学,而它又比较抽象,容易使人浅尝辄止,只能理解一些表面的东西。为此自九推之后,我深刻领悟自身不足,决定对电机学发起依次猛攻,势必要将其彻底拿下,这这只是我的粗略总结,若有空闲,我将不断完善它。

weixin_51130221的博客 1万+

Java多线程之线程同步、线程池

线程同步 多个线程操作同一个资源 并发:同一个对象被多个线程同时操作 线程同步其实就是一种等待机制,多个需要同时访问此对象的线程进入这个对象的等待池形成队列,等待前面线程使用完毕,下一个线程再使用 形成条件:队列+锁 --->解决线程安全问题 例如排队上厕所,进去一个之后锁门,认出来了锁开了,下一个才可以再进去 有锁之后容易出现性能倒置,即优先级低的线程先拿到了锁,导致优先级高的线程无法执行 需要修改的内容才需要加锁,锁太多

cao818的博客 841

AutoCAD 2024 LISP实用技巧:自定义快捷命令与高效绘图工具集

本文详细介绍了如何在AutoCAD 2024中部署和使用LISP脚本,打造高效绘图工具集。通过自定义快捷命令,如WFF(超级文字查找替换)、GQT(图层隔离)和LLTJ(智能长度统计),可大幅简化图层管理、文字编辑和测量统计等重复性操作,显著提升绘图效率。

gan8painter的博客 317

【多线程与并发】线程池的问题

什么是线程池?线程池的工作原理和使用线程池的好处? 一个线程池管理了一组工作线程,同时它还包括了一个用于放置等待执行任务的任务队列(阻塞队列)。 默认情况下,在创建了线程池后,线程池中的线程数为0。当任务提交给线程池之后的处理策略如下: 如果此时线程池中的数量小于corePoolSize(核心池的大小),即使线程池中的线程都处于空闲状态,也要创建新的线程来处理被添加的任务(也就是每来一个任务...

Soldier49Zed的博客 533

电子技术课程设计:声音音量峰值检测显示系统设计

本文介绍了声音音量峰值检测显示系统的设计方案。系统采用分立元件设计,不使用单片机和集成运放,包含电源模块、声音采集放大电路、峰值检测保持模块、比较器、A/D转换及显示控制等部分。麦克风信号经两级晶体管放大后,通过二极管-电容电路检测峰值并保持,再经A/D转换显示为数字值(0000-9999)。系统采用9V电池供电,包含启动/清除控制功能,能指示声音过低或过高状态。详细阐述了各模块电路设计、参数计算和仿真验证,并提供了完整的原理图和PCB布线方案。该系统实现了声音峰值电压的准确检测与数字显示功能。

huanghm88的专栏 255

Debezium 性能调优实战:吞吐量、延迟与资源平衡

摘要: 本文分享了团队如何通过系统性调优将Debezium从初始3,200 TPS/2.8秒延迟提升至15,200 TPS/210ms延迟的实战经验。优化涵盖四个层面:1)Debezium连接器配置(批处理、快照并行、消息精简);2)Kafka分区策略与Avro序列化缓存;3)JVM改用ZGC及OS参数调优;4)MySQL的binlog与I/O优化。关键发现包括分区数黄金公式、sync_binlog调整带来56%的I/O负载下降,以及避免盲目增大队列内存等陷阱。最终实现吞吐量提升4.75倍,并强调性能调优需

爱丹丹的博客 357

并发编程44题(含答案)

1、并发编程三要素? 1)原子性 原子性指的是一个或者多个操作,要么全部执行并且在执行的过程中不被其他操作打断,要么就全部都不执行。 2)可见性 可见性指多个线程操作一个共享变量时,其中一个线程对变量进行修改后,其他线程可以立即看到修改的结果。 实现可见性的方法: synchronized或者Lock:保证同一个时刻只有一个线程获取锁执行代码,锁释放之前把最新的值刷新到主内存,实现可见...

weixin_42034166的博客 3633

Aurix TC3xx系列MCU ADC模块简介(一)

简单介绍英飞凌Aurix TC3xx系列单片机ADC模块的特点及内部结构。

m0_38045338的博客 6359

线程池

参考地址:https://blog.youkuaiyun.com/djzhao/article/details/82192918#commentBox 如果并发的请求数量非常多,但每个线程执行的时间很短,这样就会频繁的创建和销毁线程,如此一来会大大降低系统的效率。可能出现服务器在为每个请求创建新线程和销毁线程上花费的时间和消耗的系统资源要比处理实际的用户请求的时间和资源更多。 什么时候使用线程池? 单个任务处...

孤竹彧的根据地 239

我的python学习之路

Python 是一门功能强大且易于学习的编程语言,广泛应用于数据分析、人工智能、Web 开发、自动化等领域。以下是一个 Python 学习路径的总结,帮助你系统地掌握 Python 编程。

数据知道的博客 3万+

SAP-ABAP:ABAP 开发基础概念入门:写给刚踏入 SAP 开发世界的新人

本文介绍了 ABAP 开发语言的基础概念,帮助 SAP 开发新人快速入门。主要内容包括: ABAP 的发展历程与核心优势 - 作为 SAP 平台的专属语言,ABAP 在企业级应用开发中具有深度集成、数据处理高效和长期稳定的特点 ABAP 开发环境概览 - 介绍了 SE38、SE80 等关键事务码,以及 ABAP 工作台的核心组件和开发权限管理 基础语法入门 - 重点讲解了 ABAP 特有的数据类型体系(特别是结构体和内表),并通过 Hello World 示例展示程序基本结构 文章通过对比 ABAP 与 J

baidu_35680696的博客 511

JavaSE进阶12:多线程、线程同步(锁)、线程池、

1.多线程的概念 1.1初步了解多线程 1.什么是多线程? 采用多线程技术可以同时执行多个任务(抽烟是一个任务,听音乐是一个任务,打字是一个任务) 多线程需要硬件支持 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-2aareAp3-1650346089857)(img/image-20210114221209250.png)] 现实生活中这样同时做多件事情的例子很多,看起来好像是多个任务都在做,但是本质上大脑在同一时间只做了一件事. 1.2并...

XXXZhy丶Blog 1463

AI游戏制作07——波次计时器,敌人按波次生成

AI游戏制作07——波次计时器,敌人按波次生成

qq_40572023的博客 47

你真的知道什么是多线程吗?为什么要学习多线程?

多线程是指,将原本线性执行的任务分开成若干个子任务同步执行,这样做的优点是防止线程“堵塞”,增强用户体验和程序的效率。缺点是代码的复杂程度会大大提高,而且对于硬件的要求也相应地提高。

初尘屿风的博客 1万+

汉书HE8,好用的汇编代码编写工具

汉书HE8,好用的汇编代码编写工具早期编写汇编代码所用功能强大

VC中sqlite的使用

在VC中对sqlite的使用,实现数据库大批数据的快速插入,读取数据库中的数据在ListCtrl中显示

Thread(多线程并发+线程池),超详细回顾!!!

一、不使用线程池 通过:Thread[] ths = new Thread[10];实现多线程并发 1.run方法 编写run方法,即计算方法,让10个线程同时调用run方法实现并发操作 例如:计算1~100的和 (方法一):0 ->1~10 ; 1 -> 11~20 ; …9 -> 91~100 static void call(int ix){//分段方式一(1~10) int sum = 0; for (int i = ix*10+1; i <=

WCL0520的博客 523

IEM模型,地表粗糙度模拟

利用微波反演土壤水分时候,利用IEM模型可以实现对随机地表的模拟

【python学习】最优雅的创建多线程+线程池+同步锁+限制最大并发数(使用类创建)

代码 import threading import time sem = threading.Semaphore(3) # 限制线程的最大数量为3个 class GoThread(threading.Thread): def __init__(self, num): super().__init__() self.num = num def run(self): # 总共要数多少个数 for i in range(s

AA8j的博客 516

NTscan扫描工具

ntscan是一个扫描器,可以扫描没有密码和弱密码的共享,先到配置文件中填写猜测的用户名和密码,扫描过程中右侧出现的是扫描日志。

实际场景中的多线程并发编程案例

一、CountDownLatch CountDownLatch的用法 CountDownLatch典型用法1:某一线程在开始运行前等待n个线程执行完毕。将CountDownLatch的计数器初始化为n new CountDownLatch(n) ,每当一个任务线程执行完毕,就将计数器减1 countdownlatch.countDown(),当计数器的值变为0时,在CountDownLatch上 await() 的线程就会被唤醒。一个典型应用场景就是启动一个服务时,主线程需要等待多个组件加载完毕,之后再继

iNiBuBian的博客 8996

JAVA多线程(同步锁 线程池)

多线程 同步锁 线程池

2303_82274725的博客 2279

Java 单线程池、多线程池、同步、异步的实践

使用单一线程线程池、多线程线程池、异步线程,实现作业的同步和异步执行,并实现高并发的处理。

Poison_1212的博客 3353

多线程并发环境下,数据的安全问题&&线程池

当在多线程并发的环境下,存在共享数据,并且这些数据会被修改时,就会出现线程安全问题。那么如何解决呢?可以通过让线程排队执行来解决线程安全问题,即将多线程改为串行执行。这种机制被称为线程同步机制。异步编程模型:线程之间相互独立,各自执行各自的任务,不需要等待。同步编程模型:线程之间发生等待关系,一个线程必须等待另一个线程执行完成后才能继续执行。

fj123321666的博客 980

多线程&线程池&原 子性&并发工具类

是指从软件或者硬件上实现多个线程并发执行的技术。具有多线程能力的计算机因有硬件支持而能够在同一时间执行多个线程,提升性能。多线程是并发和并行同时进行的多线程是实现并发的一个手段。一个进程可以拥有多个线程。当有多个cpu时,多个线程是可以同时执行的,这时就是并行。如果只有一个cpu,那么多个线程可以交叉重叠执行,这时就是并发了。多进程和多线程比较起来,多线程一般适用于IO密集型的任务。多进程适用于计算密集型的任务。概述。

m0_62272971的博客 185

并发操作之——并发编程实践

并发操作 并发操作之——BlockingQueue. 并发操作之——BlockingQueue并发操作一、编程里面解决生产消费者模型的几种方式1、wait() / notify()方法2、await() / signal()方法3、Semaphore信号量4、BlockingQueue阻塞队列二、synchronized和ReenTrantLock的使用场景1、synchronized2、ReenTrantLock总结 一、编程里面解决生产消费者模型的几种方式 核心:要保证生产者不会在缓冲区满时放入数

weixin_42397937的博客 3495

java多线程高并发处理

给大家整理了一些有关【线程,Java】的项目学习资料(附讲解~~):https://edu.51cto.com/course/31877.htmlhttps://edu.51cto.com/course/35714.html以一些关于【多线程】的学习资料和大家一起分享一下:https://edu.51cto.com/...

weixin_28778267的博客 114

线程池的使用:如何写出高效的多线程程序?

线程池是一种可以重复利用线程的技术,它可以减少线程的创建和销毁次数,从而提高程序的运行效率和响应速度。

程序羊的博客 2673

一篇就够!Java 多线程编程核心笔记

线程通信(Thread Communication)就是——多个线程之间共享数据,通过某种方式相互“打招呼”或“同步”进度。你可以想象两个线程就像两个人在炒菜,一个切菜、一个炒菜,它们必须“配合”着来: 🥕切好了菜 → 通知炒菜的人:“我切完啦你炒吧!🍳炒好了菜 → 也得告诉切菜的:“我炒好了你快切下一个~”这种“打招呼”的过程,就是线程通信。4.2 为什么要线程通信?因为。

2301_79897453的博客 1289

【Java高并发与多线程编程】

在当今多核处理器和分布式系统的时代,高并发和多线程编程成为了开发人员面临的重要挑战。本文将深入探讨Java高并发和多线程编程的概念、挑战以及最佳实践,并通过代码展示演示相关技术。

q58829的博客 523
上一篇: 异常及异常的处理
下一篇: lambda表达式,函数式接口
wnnSam
博客等级 码龄16年 6粉丝 19原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值