摘要:解決這兩種問題的方法是線程同步。在介紹線程同步之前,先來了解一下這兩個(gè)問題。這篇文章先介紹第一個(gè)問題線程沖突。這是一種可能的結(jié)果,也可能線程的結(jié)果被覆蓋或沒有交疊,不發(fā)生錯(cuò)誤線程沖突的結(jié)果不可預(yù)料,很難被發(fā)現(xiàn)并且修復(fù)
線程通信,主要通過共享訪問進(jìn)程資源。這種通信方式非常高效,但存在兩個(gè)問題:線程沖突(thread interference) , 內(nèi)存一致性錯(cuò)誤(memory consistensy errors)。
解決這兩種問題的方法是 線程同步(thread synchronization)。在介紹線程同步之前,先來了解一下這兩個(gè)問題。
這篇文章先介紹第一個(gè)問題:線程沖突。
線程沖突當(dāng)兩個(gè)運(yùn)行在不同線程的操作,作用在同一個(gè)數(shù)據(jù)上,會(huì)發(fā)生線程沖突 (Thread interference)
這也意味著,兩個(gè)操作分別由多個(gè)步驟組成,且兩個(gè)操作同時(shí)執(zhí)行,會(huì)導(dǎo)致步驟交疊
一個(gè)例子這里有一個(gè)類 Counter
class Counter { private int c = 0; public void increment() { c++; } public void decrement() { c--; } public int value() { return c; } }
看起來,Counter中的操作不會(huì)產(chǎn)生交疊。比如increment()方法中,唯一的 statement 是c++。
然而,即使是一個(gè)簡單的 statement,在JVM中也會(huì)轉(zhuǎn)換為多個(gè)步驟 —— 即該 statement 非原子操作
一個(gè)簡單的 statement c++,可以簡單分為三步 ( c--同理 )
取出當(dāng)前c的值
將取出的值增加1
將取出的值存儲(chǔ)至c(覆蓋原值)
假設(shè),線程A調(diào)用increment()的同時(shí),線程B調(diào)用decrement()。則兩個(gè)操作可能產(chǎn)生如下交疊
Thread A: 取出 c.
Thread B: 取出 c.
Thread A: 將取出的值增加 1.
Thread B: 將取出的值減少 -1.
Thread A: 將取出的值存儲(chǔ)至 c; c == 1.
Thread B: 將取出的值存儲(chǔ)至 c; c == -1.
線程A的結(jié)果丟失,被線程B的結(jié)果覆蓋。這是一種可能的結(jié)果,也可能線程B的結(jié)果被A覆蓋;或沒有交疊,
不發(fā)生錯(cuò)誤 —— 線程沖突 的結(jié)果不可預(yù)料,bug很難被發(fā)現(xiàn)并且修復(fù)
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/65224.html
摘要:解決這兩種問題的方法是線程同步。在介紹線程同步之前,先來了解一下這兩個(gè)問題。這篇文章介紹第二個(gè)問題內(nèi)存一致性錯(cuò)誤。 線程通信,主要通過共享訪問進(jìn)程資源。這種通信方式非常高效,但存在兩個(gè)問題:線程沖突(thread interference) , 內(nèi)存一致性錯(cuò)誤(memory consistensy errors)。 解決這兩種問題的方法是 線程同步(thread synchroniza...
摘要:關(guān)鍵字經(jīng)過編譯之后,會(huì)在同步塊的前后分別形成和這兩個(gè)字節(jié)碼指令。當(dāng)我們的把字節(jié)碼加載到內(nèi)存的時(shí)候,會(huì)對(duì)這兩個(gè)指令進(jìn)行解析。這兩個(gè)字節(jié)碼都需要一個(gè)類型的參數(shù)來指明要鎖定和解鎖的對(duì)象。最后喚醒暫停的線程。 文章簡介 前面我有文章介紹了synchronized的基本原理,這篇文章我會(huì)從jvm源碼分析synchronized的實(shí)現(xiàn)邏輯,希望讓大家有一個(gè)更加深度的認(rèn)識(shí) 內(nèi)容導(dǎo)航 從synchr...
摘要:有了這個(gè)基礎(chǔ),才能發(fā)揮作用,使得在節(jié)點(diǎn)取消和異常時(shí)能夠保證隊(duì)列在多線程下的完整性。 Doug Lea是JDK中concurrent工具包的作者,這位大神是誰可以自行g(shù)oogle。 本文淺析ReentrantLock(可重入鎖)的原理 Lock接口 showImg(https://segmentfault.com/img/bV2671?w=276&h=176); Lock接口定義了這幾個(gè)...
摘要:有了這個(gè)基礎(chǔ),才能發(fā)揮作用,使得在節(jié)點(diǎn)取消和異常時(shí)能夠保證隊(duì)列在多線程下的完整性。 Doug Lea是JDK中concurrent工具包的作者,這位大神是誰可以自行g(shù)oogle。 本文淺析ReentrantLock(可重入鎖)的原理 Lock接口 showImg(https://segmentfault.com/img/bV2671?w=276&h=176); Lock接口定義了這幾個(gè)...
摘要:有了這個(gè)基礎(chǔ),才能發(fā)揮作用,使得在節(jié)點(diǎn)取消和異常時(shí)能夠保證隊(duì)列在多線程下的完整性。 Doug Lea是JDK中concurrent工具包的作者,這位大神是誰可以自行g(shù)oogle。 本文淺析ReentrantLock(可重入鎖)的原理 Lock接口 showImg(https://segmentfault.com/img/bV2671?w=276&h=176); Lock接口定義了這幾個(gè)...
閱讀 1375·2019-08-30 15:55
閱讀 1655·2019-08-26 10:21
閱讀 3447·2019-08-23 18:28
閱讀 3383·2019-08-23 15:38
閱讀 754·2019-08-23 15:24
閱讀 2143·2019-08-23 13:59
閱讀 785·2019-08-23 11:31
閱讀 2875·2019-08-23 10:53