java并发编程实战学习笔记之基础知识与对象的共享
第二章:線程安全性
2.1 什么是線程安全性
可以被多個(gè)線程調(diào)用,并且在線程之間不會(huì)出現(xiàn)錯(cuò)誤的交互
方法內(nèi)的局部變量不需要保護(hù),因?yàn)樗鎯?chǔ)在棧中,是每個(gè)線程獨(dú)有的
2.2 原子性
一個(gè)共享變量可以定義為原子變量:atomic
多個(gè)共享變量時(shí),之間可能存在某種依賴關(guān)系,分別定義為原子變量會(huì)由于競態(tài)條件,出現(xiàn)錯(cuò)誤,比如先檢查后執(zhí)行。
競態(tài)條件:某個(gè)計(jì)算的正確性取決于多個(gè)線程的交替執(zhí)行時(shí)序時(shí)
這就需要復(fù)合操作,將多個(gè)變量的讀寫操作作為一個(gè)程序塊,接下來采用
2.3 加鎖機(jī)制
將一個(gè)復(fù)合程序塊采用內(nèi)置鎖加鎖。synchronized,把方法調(diào)用所在的對象作為一個(gè)鎖,相當(dāng)于一個(gè)互斥體,程序塊只能被該對象進(jìn)入,但是由于內(nèi)置鎖是可重入的,也就是程序塊可以被該對象多次進(jìn)入,常用于子類復(fù)寫基類的synchronized方法時(shí)。
2.4 用鎖來保護(hù)狀態(tài)
不止可用內(nèi)置鎖,還可以用顯示的鎖來執(zhí)行同步,且多個(gè)synchronized方法有相互依賴關(guān)系時(shí),還需要其他的鎖機(jī)制
2.5 活躍性與性能
由于上述方法會(huì)造成性能非常低,如果一個(gè)程序塊用時(shí)較長,則后續(xù)線程會(huì)長時(shí)間等待,應(yīng)該講鎖的粒度降低,但是在性能與程序簡單性方面要取得平衡
第三章 對象的共享
3.1 可見性
線程A修改變量i,線程B是否可立即看到?
synchronized不僅可以用來加鎖,還可以用來同步
非原子的64位操作:會(huì)被分解為兩個(gè)32位操作,因此必須在多線程環(huán)境下申明共享且可變的long或者double類型的數(shù)據(jù)時(shí),用volatile修飾,或者加鎖保護(hù)。volatile用來將變量的更新同步到其他線程,只能用于可見性,不能用于原子性。在訪問volatile變量時(shí)不會(huì)執(zhí)行加鎖操作,因此volatile是一種比synchronized更輕量級的同步機(jī)制。
volatile與加鎖的選擇:
volatile常用于簡單的狀態(tài)標(biāo)志,但不保證遞增的原子性,在1、對變量的寫入不依賴當(dāng)前值2、該變量不會(huì)與其他變量一起納入不可變條件中3、在訪問變量時(shí)不需要加鎖的情況下,才使用。
加鎖即可保證原子性,又可保證可見性。
3.2 對象的發(fā)布與逸出
當(dāng)一個(gè)對象發(fā)布時(shí),在該對象內(nèi)引用的非私有對象一同被發(fā)布。
構(gòu)造函數(shù)里的this指針很容易被逸出,可以用私有構(gòu)造函數(shù)+實(shí)例工廠來避免
3.3 線程封閉
僅在單線程內(nèi)訪問數(shù)據(jù),叫做線程封閉。比如JDBC的connection對象。從連接池獲取一個(gè)connection對象,直到用完后返回,連接池不會(huì)將該對象分配給其他線程使用。
棧封閉:申明為一個(gè)方法中的局部變量
ThreadLocal類:用于防止對可變的單實(shí)例變量或全局變量進(jìn)行共享。比如在一個(gè)進(jìn)程中使用的一個(gè)connection對象,在其內(nèi)部所有的方法都可使用,但不可被其他進(jìn)程訪問。
3.4 不變性
不可變變量:final
3.5 安全發(fā)布
多個(gè)線程間共享對象,必須確保安全的共享
可變對象必須通過安全的方式來發(fā)布,也就是必須使用同步。一個(gè)正確構(gòu)造的對象可通過以下方式來發(fā)布:1、在靜態(tài)初始化函數(shù)中初始化一個(gè)對象引用2、將對象的引用保存到volatile類型的域或者atomicReferance類型的對象中3、將對象的引用保存到某個(gè)正確構(gòu)造對象的final域中4、將對象的引用保存到由一個(gè)鎖保護(hù)的域中
轉(zhuǎn)載于:https://blog.51cto.com/muyunzhe/1719927
總結(jié)
以上是生活随笔為你收集整理的java并发编程实战学习笔记之基础知识与对象的共享的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Orchard中如何配置远端发布
- 下一篇: 使用VMDepot镜像快速部署CKAN开