摘要:如果沒有采用合適的同步機制,線程間的交叉執(zhí)行情況就無法預料。當兩個線程競爭同一資源時,如果對資源的訪問順序敏感,就稱存在競態(tài)條件。導致競態(tài)條件發(fā)生的代碼區(qū)稱作臨界區(qū)。
在同一程序中運行多個線程本身不會導致問題,問題在于多個線程訪問了相同的資源。如,同一內(nèi)存區(qū)(變量,數(shù)組,或?qū)ο螅⑾到y(tǒng)(數(shù)據(jù)庫,web services等)或文件。實際上,這些問題只有在一或多個線程向這些資源做了寫操作時才有可能發(fā)生,只要資源沒有發(fā)生變化,多個線程讀取相同的資源就是安全的。
多線程同時執(zhí)行下面的代碼可能會出錯:
public class Counter { protected long count = 0; public void add(long value){ this.count = this.count + value; } }
想象下線程A和B同時執(zhí)行同一個Counter對象的add()方法,我們無法知道操作系統(tǒng)何時會在兩個線程之間切換。JVM并不是將這段代碼視為單條指令來執(zhí)行的,而是按照下面的順序:
從內(nèi)存獲取 this.count 的值放到寄存器
將寄存器中的值增加value
將寄存器中的值寫回內(nèi)存
觀察線程A和B交錯執(zhí)行會發(fā)生什么:
this.count = 0; A: 讀取 this.count 到一個寄存器 (0) B: 讀取 this.count 到一個寄存器 (0) B: 將寄存器的值加2 B: 回寫寄存器值(2)到內(nèi)存. this.count 現(xiàn)在等于 2 A: 將寄存器的值加3 A: 回寫寄存器值(3)到內(nèi)存. this.count 現(xiàn)在等于 3
兩個線程分別加了2和3到count變量上,兩個線程執(zhí)行結(jié)束后count變量的值應(yīng)該等于5。然而由于兩個線程是交叉執(zhí)行的,兩個線程從內(nèi)存中讀出的初始值都是0。然后各自加了2和3,并分別寫回內(nèi)存。最終的值并不是期望的5,而是最后寫回內(nèi)存的那個線程的值,上面例子中最后寫回內(nèi)存的是線程A,但實際中也可能是線程B。如果沒有采用合適的同步機制,線程間的交叉執(zhí)行情況就無法預料。
當兩個線程競爭同一資源時,如果對資源的訪問順序敏感,就稱存在競態(tài)條件。導致競態(tài)條件發(fā)生的代碼區(qū)稱作臨界區(qū)。上例中add()方法就是一個臨界區(qū),它會產(chǎn)生競態(tài)條件。在臨界區(qū)中使用適當?shù)耐骄涂梢员苊飧倯B(tài)條件。
原文 Race conditions and critical sections
翻譯 He Jianjun 校對 丁一
via ifeve
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://specialneedsforspecialkids.com/yun/64055.html
摘要:父進程調(diào)用創(chuàng)建子進程。因而,一個進程的第一個線程會隨著這個進程的啟動而創(chuàng)建,這個線程被稱為該進程的主線程。另一方面,線程不可能獨立于進程存在。終止線程線程可以通過多種方式來終結(jié)同一個進程中的其他線程。 前言 不積跬步,無以至千里;不積小流,無以成江海。在學習Java多線程相關(guān)的知識前,我們首先需要去了解一點操作系統(tǒng)的進程、線程以及相關(guān)的基礎(chǔ)概念。 進程 通常,我們把一個程序的執(zhí)行稱為一...
摘要:并發(fā)需要解決的問題功能性問題線程同步面臨兩個問題,想象下有兩個線程在協(xié)作工作完成某項任務(wù)。鎖可用于規(guī)定一個臨界區(qū),同一時間臨界區(qū)內(nèi)僅能由一個線程訪問。并發(fā)的數(shù)據(jù)結(jié)構(gòu)線程安全的容器,如等。 并發(fā)指在宏觀上的同一時間內(nèi)同時執(zhí)行多個任務(wù)。為了滿足這一需求,現(xiàn)代的操作系統(tǒng)都抽象出 線程 的概念,供上層應(yīng)用使用。 這篇博文不打算詳細展開分析,而是對java并發(fā)中的概念和工具做一個梳理。沿著并發(fā)模...
閱讀 1607·2021-11-22 09:34
閱讀 1693·2019-08-29 16:36
閱讀 2674·2019-08-29 15:43
閱讀 3118·2019-08-29 13:57
閱讀 1303·2019-08-28 18:05
閱讀 1880·2019-08-26 18:26
閱讀 3250·2019-08-26 10:39
閱讀 3464·2019-08-23 18:40