【Java 核心】多线程笔记
CH1.简介
|
非阻塞I/O |
阻塞I/O |
实现方式 |
多路I/O,异步I/O |
单线程、多线程、
|
实例 |
poll, epoll |
数十万个线程的MPTL |
|
|
|
要求:安全性与活跃性
CH2. 线程安全性
状态:Shared, Mutable
instric lock monitor lock
|
synchronized (this) {...}
|
互斥体 |
POSIX pthread |
缓存机制 |
Example: 大整数因数分解 |
共享变量注意同步, 非共享变量可以不用,以达到并发性能和简单性的平衡,同时能够完美地实现安全性 |
|
CH3. 可见性
不可见性/重排序 |
(未显式同步造成的) |
E.g.private static 共享变量的更改不可见 |
最低安全性 |
最低安全性->至少不是随机值 |
除了long和double;long和double需要用volatile声明以防止读32位
|
发布publish与逸出escape |
发布是类的内容跟一起被使用,但是已经调用者无法直接访问private对象; 而逸出是错误地暴露了内部对象 |
线程封闭机制 ThreadLocal; 栈封闭; (只用于不会改变共享数据的操作吧?)
|
Immutable Object |
一定是线程安全的 |
|
|
|
|
final是说指代(reference)不可变,但是内容可以变
instrict lock
private final AtomicLong count = new AtomicLong(0);
CH4.对象的组合
主题 |
原理 |
实现 |
java中包装的并发容器 |
|
Collections 包装ArrayList和HashMap,使得线程安全
|
封闭 |
final+对象封闭+GuardedBy实现线程安全 |
|
内置锁/监视器模式 |
一种编码规范(一直使用同一个锁) |
|
委托模式 |
让ConcurrentMap等原有容器代替实现线程安全性
|
|
如果有变量间的约束关系->不能仅依靠委托->
|
|
不可变(不可外部修改)+线程不安全=>线程安全 可变+暴露+线程安全=>线程安全 |
synchronized的失效 |
大的锁只针对函数,而list内部的锁不受约束 |
>> public void synchronized putIfAbsent() {list…}不能保证threadsafe >> synchronized (list) {} 可以用来threadsafe |
CH5.基础构建模块
Vector容器的特殊操作的内部同步、线程安全; Vector外部调用的不可靠但是可以抛出异常; 迭代器 忽视toString字符串的隐式迭代器造成的线程安全问题
|
|
并发容器 CocurrentLinkedQueue BlockingQueue |
ConcurrentSkipListMap<-SortedMap ConcurrentSkipListSet<-SortedSet synchronizedMap<-TreeMap CopyOnWriteArrayList<-ArrayList |
BlockingQueue 生产消费者模式
|
E.g. 桌面搜索工具 文件建立索引 结构:完成两个任务类+写一个含阻塞队列的函数
|
阻塞型代码的中断 |
表明线程被停止,需要上层代码(调用者)知道 |
工具类1 |
确保其他所有服务都启动才释放的锁: 闭锁CountDownLatch, FutureTask Future用来返回值 >>FutureTask future = …{public void call()}; Thread(future); future.get(); E.g.粒子运动模拟计算系统
|
工具类2 |
信号量Semaphore(2值信号量为mutex)。初始值为资源数量。
|
工具类3 Barrier:类似闭锁,但是等待线程到达而不是事件
|
E.g.生命游戏的并行算法;
|
缓存 |
HashMap和同步机制 |
协程
执行有点像多线程,但协程的特点在于是一个线程执行,那和多线程比,协程有何优势?
最大的优势就是协程极高的执行效率。因为子程序切换不是线程切换,而是由程序自身控制,因此,没有线程切换的开销,和多线程比,线程数量越多,协程的性能优势就越明显。
第二大优势就是不需要多线程的锁机制,因为只有一个线程,也不存在同时写变量冲突,在协程中控制共享资源不加锁,只需要判断状态就好了,所以执行效率比多线程高很多。
因为协程是一个线程执行,那怎么利用多核CPU呢?最简单的方法是多进程+协程,既充分利用多核,又充分发挥协程的高效率,可获得极高的性能。
挂起:suspend
通知:notify
阻塞:block
唤醒: wake
参考书籍:
《Java 并发编程实战》
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通