@[toc]
從底層原理來進行分類
互斥同步
**使用各種互斥鎖 Synchronized ReentrantLock Readwritelock**
**使用同步工具
Collections.synchronized(new ArrayList)等
Vector deng**
非互斥同步
原子類
atomic包 原子類
基本類型 :
AtomicInteger 整形,
AtomicLong 長整型
AtiomicBoolean 布爾Array數組 :
AtomicIntergerArray 整形數組
AtomicLongArray 長整形數組
AtomicRefernceArray 引入數組引用類型原子類 :
AtomicReference :引用類型
AtomicStampedReference 引用類型 帶時間戳,可以解決ABA問題
升級原子類 :
後面文章會講到
Adder加法器 :
LongAdder
DoubleAdder
Accumulator累加器 :
LongAccumulator
DoubleAccumulator
結合互斥和非互斥同步
併發容器
ConcurrentHashMap
併發隊列
無同步方案不可變
final 關鍵字
ThreadLocal
1.線程安全問題
什麼是線程安全問題:當多個線程同時訪問一個全局變量,注意(做寫的操作的時候可能會受到別的線程的干擾),做讀的操作的時候不會發生線程安全問題
如 ++ , -- 修改等操作 搶火車票的操作,就會引發線程安全問題
模擬場景:
package com.yxl.demo.ThreadTest;
public class test5 {
public static void main(String[] args) {
TestDemo thread = new TestDemo();
Thread t1 = new Thread(thread,"窗口一");
Thread t2 = new Thread(thread,"窗口二");
t1.start();
t2.start();
}
}
class TestDemo implements Runnable{
//共享的火車票變量
private int count = 100;
//重寫run方法
@Override
public void run() {
while (count > 0){
try {
//休眠一下 方便出現併發問題
Thread.sleep(50);
}catch (Exception e){
e.getMessage();
}
sale();
}
}
//賣票
public void sale(){
if(count > 0){
System.out.println(Thread.currentThread().getName() +"出售 :" +(100 - count + 1));
count--;
}
}
}
運行結果如下:會發現出現賣重複票的問題
解決這個線程安全問題
內置鎖(Synchronized)
- 保證線程原子性,當先車管進入方法自動的獲取鎖,當某一個線程獲取到鎖後,其他線程就會等待,
- 鎖的特性:只有一個線程進行使用。
- 放程序執行完畢之久,就會把鎖釋放,但是鎖會降低程序的運行效率,
Synchronized 也是 重入鎖,內置鎖也是互斥鎖
使用 Synchronized 有兩種方式, 同步方法(使用的是this鎖),同步代碼塊
synchronized 修飾方法使用鎖是當前this鎖。
synchronized 修飾靜態方法使用鎖是當前類的字節碼文件
顯示鎖 (lock鎖)
解決方案 :
1.同步方法
2. 同步代碼塊
使用同步代碼塊的時候 注意(鎖一定要使用同一個鎖 )
問:如何解決多線程之間線程安全問題
*答:使用多線程之間同步synchronized或使用鎖(lock)。*
問:為什麼使用線程同步或使用鎖能解決線程安全問題呢?
*答:將可能會發生數據衝突問題(線程不安全問題),只能讓當前一個線程進行執行。代碼執行完成後釋放鎖,讓後才能讓其他線程進行執行。這樣的話就可以解決線程不安全問題。*
問:什麼是多線程之間同步
*答:當多個線程共享同一個資源,不會受到其他線程的干擾。*