Chapter 1-- 并发编程的挑战
并发编程的挑战
引入
并发编程的目的是为了让程序运行得更快,但是进行并发编程会面临以下几种挑战:
- 上下文切换
- 死锁
- 软硬件资源限制
1. 上下文切换
- 什么是上下文切换?
时间片轮转 -- 任务状态 -- 保存再加载 -- 上下文切换
cpu通过时间片分配算法来循环执行任务,任务A执行一个时间片后会切换到任务B;在切换前会保存任务A的状态,为的是:在下回切回任务A时能够再次加载任务A的状态。
【总结】任务从保存到再加载的过程就是一次上下文切换,上下文切换会影响多线程的执行速度
- 串行、并行、并发?
- 并发执行一定快于串行执行吗?
答:不一定
并发执行慢于串行的原因是:线程有创建和上下文切换的开销
- 如何减少上下文切换?
-
无锁并发编程:多线程处理数据时,避免使用锁
-
CAS算法:使用CAS算法更新数据,不需要加锁
-
使用最少线程:避免创建不必要线程
-
协程:单线程内维持多个任务的切换
2. 死锁
- 什么是死锁?
死锁:因进程之间相互竞争资源导致相互等待而无法推进的情况
- 实现一个死锁?
public class DeadLockDemo {
private static String A = "A";
private static String B = "B";
public static void main(String[] args){
new DeadLockDemo().deadLock();
}
private void deadLock(){
Thread t1 = new Thread(new Runnable() {
@Override
public void run() {
synchronized (A){
try{
Thread.currentThread().sleep(2000);
}catch (InterruptedException e){
e.printStackTrace();
}
synchronized (B){
System.out.println("1");
}
}
}
});
Thread t2 = new Thread(new Runnable() {
@Override
public void run() {
synchronized (B){
synchronized (A){
System.out.println("2");
}
}
}
});
t1.start();
t2.start();
}
}
- 怎么避免死锁?
-
避免一个线程同时获取多个锁
-
避免一个线程在锁内同时占用多个资源,尽量保证每个锁只占用一个资源
-
尝试使用定时锁替代使用内部锁机制
-
数据库锁的加锁和解锁必须在一个数据库连接里
3. 资源限制的挑战
- 什么是资源限制?
并发编程时,程序执行速度受限于资源
(资源包括软件资源和计算机硬件资源)
- 资源限制带来的问题?
并发编程中加快代码执行速度的原则是:串行-->并发;但若受限于资源,想要并发执行的代码仍然以串行方式执行,这时,代码执行速度不快反慢(增加了上下文切换和资源调度时间)
- 如何解决资源限制的问题?
-
硬件资源限制:使用集群并行执行程序
-
软件资源限制:使用资源池复用资源
- 如何在资源限制情况下并发编程
根据不同资源限制调整程序的并发度
参考书目
《Java并发编程的艺术》
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧