執行緒安全(三個條件)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;
}
}
相關文章
- 深入執行緒的wait()/notify()執行緒AI
- Java多執行緒8:wait()和notify()/notifyAll()Java執行緒AI
- Java多執行緒的wait()和notify()例子Java執行緒AI
- java多執行緒wait notify joinJava執行緒AI
- Java多執行緒 -- wait() 和 notify() 使用入門Java執行緒AI
- 【Java】【多執行緒】兩個執行緒間的通訊、wait、notify、notifyAllJava執行緒AI
- 執行緒間協作——wait、notify、notifyAll執行緒AI
- 多執行緒中的wait與notify執行緒AI
- Java多執行緒中wait 和 notify 方法理解Java執行緒AI
- 執行緒篇2:[- sleep、wait、notify、join、yield -]執行緒AI
- java多執行緒 wait() notify()簡單使用Java執行緒AI
- Java多執行緒/併發11、執行緒同步通訊:notify、waitJava執行緒AI
- 多執行緒(一)、基礎概念及notify()和wait()的使用執行緒AI
- 條件佇列大法好:wait和notify的基本語義佇列AI
- Java多執行緒中的wait/notify通訊模式Java執行緒AI模式
- 執行緒間的同步與通訊(2)——wait, notify, notifyAll執行緒AI
- 母雞下蛋例項:多執行緒通訊生產者和消費者wait/notify和condition/await/signal條件佇列執行緒AI佇列
- 多執行緒(2)-執行緒同步條件變數執行緒變數
- java多執行緒基礎篇(wait、notify、join、sleep、yeild方法)Java執行緒AI
- Java多執行緒學習(四)等待/通知(wait/notify)機制Java執行緒AI
- 條件佇列大法好:使用wait、notify和notifyAll的正確姿勢佇列AI
- muduo網路庫學習之EventLoop(二):程式(執行緒)wait/notify 和 EventLoop::runInLoopOOP執行緒AI
- Java常用的三個方法 `wait ` `notify` `notifyAll`JavaAI
- Java併發和多執行緒3:執行緒排程和有條件取消排程Java執行緒
- wait()和notify()、notifyAll()AI
- 多執行緒06:條件變數執行緒變數
- wait和notify在鎖競爭中的執行順序AI
- 執行緒安全和執行緒不安全理解執行緒
- java 執行緒安全問題,解決執行緒安全問題——同步程式碼塊,同步方法,Lock鎖,Object類中wait方法,notify方法。等待喚醒案例。Java執行緒ObjectAI
- 併發程式設計——執行緒中sleep(),yield(),join(),wait(),notify(),notifyAll()區別程式設計執行緒AI
- 多執行緒,執行緒類三種方式,執行緒排程,執行緒同步,死鎖,執行緒間的通訊,阻塞佇列,wait和sleep區別?執行緒佇列AI
- C++11 中的執行緒、鎖和條件變數C++執行緒變數
- 什麼是執行緒安全和執行緒不安全執行緒
- 如何使用ReentrantLock的條件變數,讓多個執行緒順序執行?ReentrantLock變數執行緒
- Java 併發程式設計:執行緒間的協作(wait/notify/sleep/yield/join)Java程式設計執行緒AI
- wait() and notify()AI
- java中關於執行緒間協作所用關鍵字synchronized,wait,notify的用法Java執行緒synchronizedAI
- 執行緒安全和不可重入執行緒