理論:第八章:線程是什么,有幾種實(shí)現(xiàn)方式,它們之間的區(qū)別是什么,線程池實(shí)現(xiàn)原理,JUC并發(fā)包,ThreadLocal與Lock和Synchronize區(qū)別
什么是線程?講個故事給你聽,讓你沒法去背這個題,地址:https://blog.csdn.net/java_wxid/article/details/94131223
有幾種實(shí)現(xiàn)方式?
繼承Thread類
實(shí)現(xiàn)Runnable接口
實(shí)現(xiàn)Callable接口
線程池方式
優(yōu)缺點(diǎn)
1.繼承Thread類
優(yōu)點(diǎn) 、代碼簡單 。
缺點(diǎn) 、該類無法集成別的類。
2.實(shí)現(xiàn)Runnable接口
優(yōu)點(diǎn) 、繼承其他類。 同一實(shí)現(xiàn)該接口的實(shí)例可以共享資源。
缺點(diǎn) 、代碼復(fù)雜
3.實(shí)現(xiàn)Callable
優(yōu)點(diǎn) 、可以獲得異步任務(wù)的返回值
4.線程池 、實(shí)現(xiàn)自動化裝配,易于管理,循環(huán)利用資源。
代碼實(shí)現(xiàn)案例:
繼承Thread類,并重寫里面的run方法
class A extends Thread{
public void run(){
for(int i=1;i<=100;i++){
System.out.println("-----------------"+i);
}
}
}
A a = new A();
a.start();
實(shí)現(xiàn)Runnable接口,并實(shí)現(xiàn)里面的run方法
class B implements Runnable{
public void run(){
for(int i=1;i<=100;i++){
System.out.println("-----------------"+i);
}
}
}
B b = new B();
Thread t = new Thread(b);
t.start();
實(shí)現(xiàn)Callable
class A implements Callable<String>{
public String call() throws Exception{
//...
}
}
FutureTask<String> ft = new FutureTask<>(new A());
new Thread(ft).start();
線程池
ExcutorService es = Executors.newFixedThreadPool(10);
es.submit(new Runnable(){//任務(wù)});
es.submit(new Runnable(){//任務(wù)});
...
es.shutdown();
問題擴(kuò)展
在Java中Lock接口比synchronized塊的優(yōu)勢是什么?你需要實(shí)現(xiàn)一個高效的緩存,它允許多個用戶讀,但只允許一個用戶寫,以此來保持它的完整性,你會怎樣去實(shí)現(xiàn)它?
整體上來說Lock是synchronized的擴(kuò)展版,Lock提供了無條件的、可輪詢的(tryLock方法)、定時的(tryLock帶參方法)、可中斷的(lockInterruptibly)、可多條件隊(duì)列的(newCondition方法)鎖操作。另外Lock的實(shí)現(xiàn)類基本都支持非公平鎖(默認(rèn))和公平鎖,synchronized只支持非公平鎖,當(dāng)然,在大部分情況下,非公平鎖是高效的選擇。
線程池的實(shí)現(xiàn)原理:https://blog.csdn.net/java_wxid/article/details/101844786
JUC并發(fā)包:
volatile的三大特性:https://blog.csdn.net/java_wxid/article/details/97611028
CompareAndSwap底層原理:https://blog.csdn.net/java_wxid/article/details/97611037
AtomicReference原子引用:https://blog.csdn.net/java_wxid/article/details/97611046
CountDownLatch倒計(jì)時器:https://blog.csdn.net/java_wxid/article/details/99168098
CyclicBarrier循環(huán)柵欄:https://blog.csdn.net/java_wxid/article/details/99171155
Semaphore信號燈:https://blog.csdn.net/java_wxid/article/details/99174538
ThreadLocal與Lock和Synchronize區(qū)別
ThreadLocal與Lock和Synchronize區(qū)別
ThreadLocal為每一個線程都提供了變量的副本,使得每個線程在某一時間訪問到的并不是同一個對象,這樣就隔離了多個線程對數(shù)據(jù)的數(shù)據(jù)共享。ThreadLocal采用了“以空間換時間”的方式,為每一個線程都提供了一份變量,因此可以同時訪問而互不影響。
synchronized是利用鎖的機(jī)制,使變量或代碼塊在某一時該只能被一個線程訪問。同步機(jī)制采用了“以時間換空間”的方式,僅提供一份變量,讓不同的線程排隊(duì)訪問。
如果一個代碼塊被synchronized關(guān)鍵字修飾,當(dāng)一個線程獲取了對應(yīng)的鎖,并執(zhí)行該代碼塊時,其他線程便只能一直等待直至占有鎖的線程釋放鎖。事實(shí)上,占有鎖的線程釋放鎖一般會是以下三種情況之一:
占有鎖的線程執(zhí)行完了該代碼塊,然后釋放對鎖的占有;
占有鎖線程執(zhí)行發(fā)生異常,此時JVM會讓線程自動釋放鎖;
占有鎖線程進(jìn)入 WAITING 狀態(tài)從而釋放鎖,例如在該線程中調(diào)用wait()方法等。
synchronized 是Java語言的內(nèi)置特性,可以輕松實(shí)現(xiàn)對臨界資源的同步互斥訪問。那么,為什么還會出現(xiàn)Lock呢?試考慮以下三種情況:
Case 1 :
在使用synchronized關(guān)鍵字的情形下,假如占有鎖的線程由于要等待IO或者其他原因(比如調(diào)用sleep方法)被阻塞了,但是又沒有釋放鎖,那么其他線程就只能一直等待,別無他法。這會極大影響程序執(zhí)行效率。因此,就需要有一種機(jī)制可以不讓等待的線程一直無期限地等待下去(比如只等待一定的時間 (解決方案:tryLock(long time, TimeUnit unit)) 或者 能夠響應(yīng)中斷 (解決方案:lockInterruptibly())),這種情況可以通過 Lock 解決。
Case 2 :
我們知道,當(dāng)多個線程讀寫文件時,讀操作和寫操作會發(fā)生沖突現(xiàn)象,寫操作和寫操作也會發(fā)生沖突現(xiàn)象,但是讀操作和讀操作不會發(fā)生沖突現(xiàn)象。但是如果采用synchronized關(guān)鍵字實(shí)現(xiàn)同步的話,就會導(dǎo)致一個問題,即當(dāng)多個線程都只是進(jìn)行讀操作時,也只有一個線程在可以進(jìn)行讀操作,其他線程只能等待鎖的釋放而無法進(jìn)行讀操作。因此,需要一種機(jī)制來使得當(dāng)多個線程都只是進(jìn)行讀操作時,線程之間不會發(fā)生沖突。同樣地,Lock也可以解決這種情況 (解決方案:ReentrantReadWriteLock) 。
Case 3 :
我們可以通過Lock得知線程有沒有成功獲取到鎖 (解決方案:ReentrantLock) ,但這個是synchronized無法辦到的。
上面提到的三種情形,我們都可以通過Lock來解決,但 synchronized 關(guān)鍵字卻無能為力。事實(shí)上,Lock 是 java.util.concurrent.locks包 下的接口,Lock 實(shí)現(xiàn)提供了比 synchronized 關(guān)鍵字 更廣泛的鎖操作,它能以更優(yōu)雅的方式處理線程同步問題。也就是說,Lock提供了比synchronized更多的功能。但是要注意以下幾點(diǎn):
1)synchronized是Java的關(guān)鍵字,因此是Java的內(nèi)置特性,是基于JVM層面實(shí)現(xiàn)的。而Lock是一個Java接口,是基于JDK層面實(shí)現(xiàn)的,通過這個接口可以實(shí)現(xiàn)同步訪問;
2)采用synchronized方式不需要用戶去手動釋放鎖,當(dāng)synchronized方法或者synchronized代碼塊執(zhí)行完之后,系統(tǒng)會自動讓線程釋放對鎖的占用;而 Lock則必須要用戶去手動釋放鎖,如果沒有主動釋放鎖,就有可能導(dǎo)致死鎖現(xiàn)象。
關(guān)于讀寫鎖:https://blog.csdn.net/java_wxid/article/details/99165717