執行緒安全(三個條件)Synchronzied,wait和notify
原子性
記憶體可見性
程式碼重排序
執行緒不安全:執行結果和預期結果之間出現概率性
概率性的來源:執行緒切換的隨機性
經過三個條件的放大:原子性/記憶體可見性/程式碼重排序
程式碼實踐
ArrayList
如何設計程式碼,進而使得程式碼具備執行緒安全問題
思考:
- 執行緒安全是什麼?
- 隨機性來自何處?
- 隨機性如何傳遞出來?
- JVM記憶體區域劃分的共享和私有?
實踐:
a) 哪些情況需要寫多執行緒程式碼?
b) 寫了多執行緒之後,哪裡出現執行緒安全的風險了?
c) 如何對風險進行保護?
鎖機制
原子性+可見性+程式碼重排序起到一定的保護
Synchronzied關鍵字
Synchronzied關鍵子的作用
Volatile的不穩定機制
Volatile Person p;
P = new Person(…); 可以保證一定是1->2->3的順序
單例模式
阻塞佇列
執行緒通訊
Wait如果有多個,notify會喚醒隨機的一個執行緒(不保證哪一個)
Notifyall把所有的都叫醒
public class 獲取反射類引用 {
static class Person {}
public static void main(String[] args) {
Person p1 = new Person();
Person p2 = new Person();
// 通過物件引用獲取反射類物件引用
Class<? extends Person> c1 = p1.getClass();
Class<? extends Person> c2 = p2.getClass();
// 通過類名獲取反射類物件引用
Class<Person> c3 = Person.class;
System.out.println(c1 == c2);
System.out.println(c1 == c3);
}
}
public class 修復之前的執行緒安全問題 {
private static final int COUNT = 100_0000;
private static int n = 0;
private static Object lock = new Object();
static class Adder extends Thread {
@Override
public void run() {
synchronized (lock) {
for (int i = 0; i < COUNT; i++) {
n++;
}
}
}
}
static class Suber extends Thread {
@Override
public void run() {
synchronized (lock) {
for (int i = 0; i < COUNT; i++) {
n--;
}
}
}
}
public static void main(String[] args) throws InterruptedException {
Thread t1 = new Adder();
Thread t2 = new Suber();
t1.start();
t2.start();
t1.join();
t2.join();
System.out.println(n);
}
}
public class Synchronized的語法使用示例 {
// 同步方法
synchronized int add(int a, int b) {
return 0;
}
synchronized static void sayHello() {
}
// 同步程式碼塊 —— 能出現語句的地方
static void someMethod() {
Object object = new Object();
synchronized (object) {
}
}
}
package 單例模型;
// 執行緒安全 + 簡單
// 構造的早,如果不用,就浪費空間了
public class Hungry {
private Hungry() {}
private static Hungry instance = new Hungry(); // 只會有這麼一個物件
public static Hungry getInstance() {
return instance;
}
}
package 單例模型;
// 不是執行緒安全的
public class LazyVersion1 {
private static LazyVersion1 instance = null;
public static LazyVersion1 getInstance() {
// 有人要用到該物件了
if (instance == null) {
// 第一次的時候,進行例項化,以後不再進行
instance = new LazyVersion1();
}
return instance;
}
}
package 單例模型;
// 執行緒安全了
// 效能不高
public class LazyVersion2 {
private static LazyVersion2 instance = null;
public static LazyVersion2 getInstance() {
synchronized (LazyVersion2.class) {
if (instance == null) {
instance = new LazyVersion2();
}
}
return instance;
}
}
package 單例模型;
// 1. 為什麼要二次判斷
// 2. 效能是怎麼提高的
// 3. instance = new LazyVersion3() 可能會被重排序成 1 -> 3 -> 2
public class LazyVersion3 {
private static LazyVersion3 instance = null;
public static LazyVersion3 getInstance() {
if (instance == null) {
// 100年的1秒
synchronized (LazyVersion3.class) {
// 能 保證 instance 還是 null
if (instance == null) {
instance = new LazyVersion3();
}
}
}
return instance;
}
}
package 單例模型;
// 1. 為什麼要二次判斷
// 2. 效能是怎麼提高的
public class LazyVersion4 {
// volatile 的目的:
// 保護 instance = new LazyVersion4(); 一定是 1 -> 2 -> 3 的順序
// 而不至於出現,其他執行緒看到 instance != null,但執行的是一個沒有被初始化完的物件。
private static volatile LazyVersion4 instance = null;
public static LazyVersion4 getInstance() {
if (instance == null) {
// 100年的1秒
synchronized (LazyVersion4.class) {
// 能 保證 instance 還是 null
if (instance == null) {
instance = new LazyVersion4();
}
}
}
return instance;
}
}
相關文章
- Java多執行緒 -- wait() 和 notify() 使用入門Java執行緒AI
- 【Java】【多執行緒】兩個執行緒間的通訊、wait、notify、notifyAllJava執行緒AI
- Java多執行緒中wait 和 notify 方法理解Java執行緒AI
- java多執行緒 wait() notify()簡單使用Java執行緒AI
- 執行緒篇2:[- sleep、wait、notify、join、yield -]執行緒AI
- 多執行緒(一)、基礎概念及notify()和wait()的使用執行緒AI
- 條件佇列大法好:wait和notify的基本語義佇列AI
- Java多執行緒中的wait/notify通訊模式Java執行緒AI模式
- 母雞下蛋例項:多執行緒通訊生產者和消費者wait/notify和condition/await/signal條件佇列執行緒AI佇列
- 執行緒間的同步與通訊(2)——wait, notify, notifyAll執行緒AI
- java多執行緒基礎篇(wait、notify、join、sleep、yeild方法)Java執行緒AI
- Java多執行緒學習(四)等待/通知(wait/notify)機制Java執行緒AI
- Java常用的三個方法 `wait ` `notify` `notifyAll`JavaAI
- 多執行緒(2)-執行緒同步條件變數執行緒變數
- 併發程式設計——執行緒中sleep(),yield(),join(),wait(),notify(),notifyAll()區別程式設計執行緒AI
- java 執行緒安全問題,解決執行緒安全問題——同步程式碼塊,同步方法,Lock鎖,Object類中wait方法,notify方法。等待喚醒案例。Java執行緒ObjectAI
- 多執行緒06:條件變數執行緒變數
- 多執行緒,執行緒類三種方式,執行緒排程,執行緒同步,死鎖,執行緒間的通訊,阻塞佇列,wait和sleep區別?執行緒佇列AI
- Python執行緒條件變數Condition解析Python執行緒變數
- 如何使用ReentrantLock的條件變數,讓多個執行緒順序執行?ReentrantLock變數執行緒
- 什麼是執行緒安全和執行緒不安全執行緒
- Python執行緒專題7:條件變數Python執行緒變數
- Java-併發-wait()、notify()和notifyAll()JavaAI
- Java 中的 Wait 和 Notify 機制JavaAI
- 多執行緒中使用Lock鎖定多個條件Condition的使用執行緒
- 併發程式設計之Wait和Notify程式設計AI
- 三個執行緒迴圈列印123-多執行緒執行緒
- 多執行緒併發篇——三件兵器執行緒
- 解決多執行緒競爭條件——臨界區執行緒
- 多執行緒程式設計介紹-條件變數執行緒程式設計變數
- 執行緒安全執行緒
- 多執行緒系列之 執行緒安全執行緒
- iOS 多執行緒之執行緒安全iOS執行緒
- Java執行緒(一):執行緒安全與不安全Java執行緒
- 多執行緒與併發-----條件阻塞Condition的應用執行緒
- 執行緒和執行緒池執行緒
- 【多執行緒總結(二)-執行緒安全與執行緒同步】執行緒
- 【Java多執行緒】執行緒安全的集合Java執行緒