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并发编程的艺术》
标签:Chapter,--,编程,并发,死锁,切换,上下文,资源 来源: https://www.cnblogs.com/Claire-is-here/p/16475746.html