1、并發(fā)編程的挑戰(zhàn)來自哪里?
- 1.1、上下文切換
- 1.2、死鎖
- 1.3、資源限制的挑戰(zhàn)
1.1、上下文切換
單核處理器也支持多線程執(zhí)行代碼,CPU通過給每個(gè)線程分配CPU時(shí)間片來實(shí)現(xiàn)這個(gè)機(jī)制。時(shí)間片是CPU分配給各個(gè)線程的時(shí)間,因?yàn)闀r(shí)間片非常短,所以CPU通過不停地切換線程執(zhí)行,讓我們感覺多個(gè)線程是同時(shí)執(zhí)行的,時(shí)間片一般是幾十毫秒(ms)
CPU通過時(shí)間片分配算法來循環(huán)執(zhí)行任務(wù),當(dāng)前任務(wù)執(zhí)行完一個(gè)時(shí)間片之后會切換到下一個(gè)任務(wù),但是在切換之前會保存上一個(gè)任務(wù)的狀態(tài),以便下次切換回這個(gè)任務(wù)的時(shí)候還可以加載回之前的狀態(tài)。所以任務(wù)從保存到重載的這一過程就是一次上下文切換。
多線程執(zhí)行任務(wù)一定快?
答案是不一定,因?yàn)閯?chuàng)建線程和上下文切換會占用一定的時(shí)間。
如何減少上下文切換
- 無鎖并發(fā)編程
- CAS算法
- 使用最少線程執(zhí)行
1.2、死鎖
線程之間相互持有對方資源而不釋放會導(dǎo)致死鎖
package main.java.com.robot.demo;
/**
* @author: 會跳舞的機(jī)器人
* @date: 2017/8/9 16:30
* @description: java死鎖案例
*/
public class DeadLock {
private static String firstMonitor = "A";
private static String secondMonitor = "B";
public static void main(String[] args) {
Thread thread1 = new Thread(new Runnable() {
@Override
public void run() {
synchronized (firstMonitor) {
System.out.println("thread1 locked firstMonitor");
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized (secondMonitor) {
System.out.println("thread1 locked secondMonitor");
}
}
}
});
Thread thread2 = new Thread(new Runnable() {
public void run() {
synchronized (secondMonitor) {
System.out.println("thread2 locked secondMonitor");
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized (firstMonitor) {
System.out.println("thread2 locked firstMonitor");
}
}
}
});
thread1.start();
thread2.start();
}
}
1、3資源限制的挑戰(zhàn)
并不是說線程越多,代碼執(zhí)行速度會更快,還取決于硬件資源。所以根據(jù)不同的硬件資源配置合適的并發(fā)數(shù)顯得尤為重要。