一,線程的三大特性:原子性、可見性、有序性
1)原子性,即一個(gè)操作或者多個(gè)操作要么全部執(zhí)行并且執(zhí)行的過程不會(huì)被任何因素打斷,要么就都不執(zhí)行。原子性其實(shí)就是保證數(shù)據(jù)一致、線程安全一部分。
2)可見性,即當(dāng)多個(gè)線程訪問同一個(gè)變量時(shí),一個(gè)線程修改了這個(gè)變量的值,其他線程能夠立即看得到修改的值。
3)有序性,即程序執(zhí)行的順序按照代碼的先后順序執(zhí)行。
二、JAVA多線程的內(nèi)存模型
共享內(nèi)存模型指的就是Java內(nèi)存模型(簡稱JMM),JMM決定一個(gè)線程對(duì)共享變量的寫入時(shí),能對(duì)另一個(gè)線程可見。從抽象的角度來看,JMM定義了線程和主內(nèi)存之間的抽象關(guān)系:線程之間的共享變量存儲(chǔ)在主內(nèi)存(main memory)中,每個(gè)線程都有一個(gè)私有的本地內(nèi)存(local memory),本地內(nèi)存中存儲(chǔ)了該線程以讀/寫共享變量的副本。本地內(nèi)存是JMM的一個(gè)抽象概念,并不真實(shí)存在。它涵蓋了緩存,寫緩沖區(qū),寄存器以及其他的硬件和編譯器優(yōu)化。
從上圖來看,線程A與線程B之間如要通信的話,必須要經(jīng)歷下面2個(gè)步驟:
1. 首先,線程A把本地內(nèi)存A中更新過的共享變量刷新到主內(nèi)存中去。
2. 然后,線程B到主內(nèi)存中去讀取線程A之前已更新過的共享變量。
總結(jié):什么是Java內(nèi)存模型:java內(nèi)存模型簡稱jmm,定義了一個(gè)線程對(duì)另一個(gè)線程可見。共享變量存放在主內(nèi)存中,每個(gè)線程都有自己的本地內(nèi)存,當(dāng)多個(gè)線程同時(shí)訪問一個(gè)數(shù)據(jù)的時(shí)候,可能本地內(nèi)存沒有及時(shí)刷新到主內(nèi)存,所以就會(huì)發(fā)生線程安全問題。
三、Volatile
Volatile 關(guān)鍵字的作用是變量在多個(gè)線程之間可見。
1)由于線程之間是不可見的,讀取的是副本,所以會(huì)沒有及時(shí)讀取到主內(nèi)存結(jié)果。解決辦法使用Volatile關(guān)鍵字將解決線程之間可見性, 強(qiáng)制線程每次讀取該值的時(shí)候都去“主內(nèi)存”中取值
2)Volatile非原子性
由于Volatile不具有原子性,需要Atomic原子類。
AtomicInteger atomicInteger = new AtomicInteger(0);
3)volatile與synchronized區(qū)別
僅靠volatile不能保證線程的安全性。(非原子性)
a、volatile輕量級(jí),只能修飾變量。synchronized重量級(jí),還可修飾方法
b、volatile只能保證數(shù)據(jù)的可見性,不能用來同步,因?yàn)槎鄠€(gè)線程并發(fā)訪問volatile修飾的變量不會(huì)阻塞。
c、synchronized不僅保證可見性,而且還保證原子性,因?yàn)椋挥蝎@得了鎖的線程才能進(jìn)入臨界區(qū),從而保證臨界區(qū)中的所有語句都全部執(zhí)行。多個(gè)線程爭搶synchronized鎖對(duì)象時(shí),會(huì)出現(xiàn)阻塞。
d、線程安全性
線程安全性包括兩個(gè)方面,①可見性。②原子性。
從上面自增的例子中可以看出:僅僅使用volatile并不能保證線程安全性。而synchronized則可實(shí)現(xiàn)線程的安全性。
四、ThreadLocal
1)ThreadLocal提高一個(gè)線程的局部變量,訪問某個(gè)線程擁有自己局部變量。當(dāng)使用ThreadLocal維護(hù)變量時(shí),ThreadLocal為每個(gè)使用該變量的線程提供獨(dú)立的變量副本,所以每一個(gè)線程都可以獨(dú)立地改變自己的副本,而不會(huì)影響其它線程所對(duì)應(yīng)的副本。
2)ThreadLocal類的接口方法
ThreadLocal類接口很簡單,只有4個(gè)方法,我們先來了解一下:
a、void set(Object value)設(shè)置當(dāng)前線程的線程局部變量的值。
b、public Object get()該方法返回當(dāng)前線程所對(duì)應(yīng)的線程局部變量。
c、public void remove()將當(dāng)前線程局部變量的值刪除,目的是為了減少內(nèi)存的占用。需要指出的是,當(dāng)線程結(jié)束后,對(duì)應(yīng)該線程的局部變量將自動(dòng)被垃圾回收,所以顯式調(diào)用該方法清除線程的局部變量并不是必須的操作,但它可以加快內(nèi)存回收的速度。
d、protected Object initialValue()返回該線程局部變量的初始值,該方法是一個(gè)protected的方法,顯然是為了讓子類覆蓋而設(shè)計(jì)的。這個(gè)方法是一個(gè)延遲調(diào)用方法,在線程第1次調(diào)用get()或set(Object)時(shí)才執(zhí)行,并且僅執(zhí)行1次。ThreadLocal中的缺省實(shí)現(xiàn)直接返回一個(gè)null。
public static ThreadLocal<Integer> threadLocal = new ThreadLocal<Integer>() {
protected Integer initialValue() {
return 0;
};
};
3)ThreadLoca實(shí)現(xiàn)原理
ThreadLoca通過map集合
Map.put(“當(dāng)前線程”,值);
五、線程池
1)什么是線程池
線程池是指在初始化一個(gè)多線程應(yīng)用程序過程中創(chuàng)建一個(gè)線程集合,然后在需要執(zhí)行新的任務(wù)時(shí)重用這些線程而不是新建一個(gè)線程。線程池中線程的數(shù)量通常完全取決于可用內(nèi)存數(shù)量和應(yīng)用程序的需求。然而,增加可用線程數(shù)量是可能的。線程池中的每個(gè)線程都有被分配一個(gè)任務(wù),一旦任務(wù)已經(jīng)完成了,線程回到池子中并等待下一次分配任務(wù)。
2)線程池的作用
基于以下幾個(gè)原因在多線程應(yīng)用程序中使用線程是必須的:
1. 線程池改進(jìn)了一個(gè)應(yīng)用程序的響應(yīng)時(shí)間。由于線程池中的線程已經(jīng)準(zhǔn)備好且等待被分配任務(wù),應(yīng)用程序可以直接拿來使用而不用新建一個(gè)線程。
2. 線程池節(jié)省了CLR 為每個(gè)短生存周期任務(wù)創(chuàng)建一個(gè)完整的線程的開銷并可以在任務(wù)完成后回收資源。
3. 線程池根據(jù)當(dāng)前在系統(tǒng)中運(yùn)行的進(jìn)程來優(yōu)化線程時(shí)間片。
4. 線程池允許我們開啟多個(gè)任務(wù)而不用為每個(gè)線程設(shè)置屬性。
5. 線程池允許我們?yōu)檎趫?zhí)行的任務(wù)的程序參數(shù)傳遞一個(gè)包含狀態(tài)信息的對(duì)象引用。
6. 線程池可以用來解決處理一個(gè)特定請(qǐng)求大線程數(shù)量限制問題。
3)線程池的4種創(chuàng)建方式
Java通過Executors(jdk1.5并發(fā)包)提供四種線程池,分別為:
1.newCachedThreadPool創(chuàng)建一個(gè)可緩存線程池,如果線程池長度超過處理需要,可靈活回收空閑線程,若無可回收,則新建線程。(常用)
2.newFixedThreadPool 創(chuàng)建一個(gè)定長線程池,可控制線程大并發(fā)數(shù),超出的線程會(huì)在隊(duì)列中等待。
3.newScheduledThreadPool 創(chuàng)建一個(gè)定長線程池,支持定時(shí)及周期性任務(wù)執(zhí)行。
4.newSingleThreadExecutor 創(chuàng)建一個(gè)單線程化的線程池,它只會(huì)用唯一的工作線程來執(zhí)行任務(wù),保證所有任務(wù)按照指定順序(FIFO, LIFO, 優(yōu)先級(jí))執(zhí)行。
當(dāng)前名稱:Java多線程的三大特性,線程池,JMM(Java共享內(nèi)存)-創(chuàng)新互聯(lián)
當(dāng)前網(wǎng)址:http://jinyejixie.com/article10/dedigo.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供品牌網(wǎng)站建設(shè)、服務(wù)器托管、電子商務(wù)、小程序開發(fā)、網(wǎng)站營銷、建站公司
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場,如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)
猜你還喜歡下面的內(nèi)容