第一章-并發程式設計的挑戰
-
上下文切換
CPU通過時間片算法來循環執行任務,目前任務執行一個時間片會切換到下一個任務。但是,在切換前會儲存上一個任務的狀态,以便于下次切換回這個任務時,可以再次加載這個任務的狀态。從任務的儲存到在加載就是一次上下文切換
CPU是通過給每個線程配置設定cpu時間片來實作多線程的,時間片特别短,一般為幾十毫秒,cpu通過不同的切換線程,讓我們感覺到多線程是同時工作的。
-
如何減少上下文切換
無所并發程式設計:多線程競争鎖,會引起上下文切換, 是以要避免使用鎖
CAS算法:Java中的Atomic包使用CAS來更新資料,不需要加鎖
使用最少線程:避免建立不需要的線程
協程:在單線程裡實作多任務的排程,并在單線程裡維持多個任務間的排程(?)
public class DeadLockDemo {
private static String A = "A";
private static String B = "BA";
public static void main(String[] args) {
DeadLockDemo.dedaLock();
}
public static void dedaLock() {
Thread t1 = new Thread(new Runnable() {
@Override
public void run() {
synchronized (A) {
try {
Thread.sleep(2000);
} catch (Exception 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();
}
}
上面代碼示範了死鎖的場景,AB互相等待對方釋放鎖。通過dump可以看到
以上資訊告訴我們在33和22行代碼發生了死鎖。
3.避免死鎖的方法
避免一個線程同時擷取多個鎖
避免一個線程在鎖内同時占有多個資源,盡量保證每個鎖隻占有一個資源
嘗試使用定時鎖,使用Lock.tryLock來替代使用内部鎖機制