1.java線程中的守護(hù)線程和用戶線程概述
? ? ? ? ? ? 只要當(dāng)JVM實(shí)例中尚存任何一個非守護(hù)線程沒有結(jié)束,守護(hù)線程就全部工作,只有當(dāng)最后一個非守護(hù)線程結(jié)束時,守護(hù)線程隨著JVM一同結(jié)束
? ? ? ? ? ? user和Daemon兩者幾乎沒有區(qū)別,唯一的不同之處就在于虛擬機(jī)的離開,如果User Thread已經(jīng)全部退出,只剩下Daemon Thread存在,虛擬機(jī)也就退出了,以為沒有了被守護(hù)者,也就沒有繼續(xù)運(yùn)行的必要了,守護(hù)線程最典型的例子就是GC
2.什么是多線程上線文切換
? ? ? ? 多線程會共同使用一組計(jì)算機(jī)上的CPU,而線程數(shù)大于給程序分配的CPU數(shù)量時,為了讓各個線程有有機(jī)會執(zhí)行,就需要輪轉(zhuǎn)是用CPU
? ? ? ? 在上下文切換過程中,CPU會停止處理當(dāng)前運(yùn)行的程序,并保存當(dāng)前程序的具體位置以后繼續(xù)運(yùn)行
? ? ? ? 上下文切換是存儲和恢復(fù)CPU狀態(tài)的過程,它使得線程執(zhí)行能夠從中斷點(diǎn)恢復(fù)執(zhí)行,上下文切換是多任務(wù)操作系統(tǒng)和多線程環(huán)境的基本特
3.java中用到的線程調(diào)度算法是什么?
? ? ? ? 有兩種調(diào)度模型:分時調(diào)度和搶占式調(diào)度模型
? ? ? ? 分時調(diào)度:讓所有的線程輪流獲得CPU使用權(quán),并且平均分配占用CPU的時間片
? ? ? ? 搶占式調(diào)度模型:是指讓運(yùn)行池中優(yōu)先級高的線程占用CPU,如果可運(yùn)行池中的線程優(yōu)先級相同,就隨機(jī)選擇一個線程,使其占用cpu
4.線程的生命周期?
????????線程一共有5中狀態(tài),分別如下:
? ? ? ? 1.新建:當(dāng)創(chuàng)建一個Thread類的一個實(shí)例時,此線程會進(jìn)入新建狀態(tài)
? ? ? ? 2.可運(yùn)行:線程對象創(chuàng)建后,其他線程調(diào)用了該對象的start方法,該狀態(tài)的線程位于可運(yùn)行線程池中,等待被線程調(diào)度選中,獲取cpu使用權(quán)
? ? ? ? 3.運(yùn)行:線程獲得CPU資源,正在執(zhí)行run()方法
? ? ? ? 4.死亡:當(dāng)線程執(zhí)行完畢或被其他線程殺死,線程就進(jìn)入死亡狀態(tài),這是線程不可能進(jìn)入就緒等待狀態(tài)
? ? ? ? ? ? ? ? 正常終止:正常運(yùn)行完run()方法
? ? ? ? ? ? ? ? 異常終止:調(diào)用stop()方法,讓一個線程終止運(yùn)行
? ? ? ? 5.阻塞:由于某種原因?qū)е抡谶\(yùn)行的線程讓出cpu并暫停自己的執(zhí)行,即進(jìn)入阻塞狀,阻塞的情況有三種:
? ? ? ? ? ? ? ? ? ? 1.睡眠:sleep(),可以使線程進(jìn)入睡眠模式
? ? ? ? ? ? ? ? ? ? 2.等待:調(diào)用wait()方法,調(diào)用notify()回到就緒狀態(tài)
? ? ? ? ? ? ? ? ? ? 3.被另外一個線程阻塞:調(diào)用suspend()方法

5.如何結(jié)束一個一直運(yùn)行的線程
? ? ? ? 方式一:使用退出標(biāo)志位,這個flag變量要多線程可見
? ? ? ? 方式二:線程經(jīng)常會由于一些事件而發(fā)生阻塞,使線程進(jìn)入不可運(yùn)行狀態(tài),這里建議使用interrupt(),而不使用stop(),因?yàn)樵摲椒m然不會中斷一個正在運(yùn)行的線程,但是它可以是一個被阻塞的線程拋出異常,從而使線程提前結(jié)束阻塞狀態(tài),退出堵塞代碼
? ??????在java中主要有3個相關(guān)方法,interrupt(),isInterrupted()和interrupted()
? ??????interrupt(),在一個線程中調(diào)用另一個線程的interrupt()方法,即會向那個線程發(fā)出信號——線程中斷狀態(tài)已被設(shè)置。至于那個線程何去何從,由具體的代碼實(shí)現(xiàn)決定。
????????isInterrupted(),用來判斷當(dāng)前線程的中斷狀態(tài)(true or false)。
????????interrupted()是個Thread的static方法,用來恢復(fù)中斷狀態(tài)(?。。。?/p>
6.創(chuàng)建線程的方式及實(shí)現(xiàn)
? ? 方式一,繼承 Thread 類創(chuàng)建線程類。? ? ??
? ? ? ? ? ? ? 缺點(diǎn):extends了Thread,重寫run()方法,所以不能再繼承別的類了
? ? 方式二,通過 Runnable 接口創(chuàng)建線程類。
? ? ? ? ? ? ? implements了Runnable,并實(shí)現(xiàn)run()方法
? ? 方式三,通過 Callable 和 Future 創(chuàng)建線程。
?????????????implements了Callable,實(shí)現(xiàn)call()方法
7.如何使用wait+notify實(shí)現(xiàn)通知機(jī)制
????????Object 類的 wait 和 notify方法實(shí)現(xiàn)線程阻塞
? ? ? ? 1.首先,wait和notify方法是針對對象的,調(diào)用任意對象的wait和notify都將導(dǎo)致線程阻塞,阻塞的同時也將釋放該對象的鎖,相應(yīng)的調(diào)用任意對象的notify方法將隨機(jī)解除該對象阻塞的線程,但它需要重新獲取該對象的鎖,直到獲取成功才往下執(zhí)行
? ? ? ? 2.其次,wait和notify方法必須在synchtonized塊或方法中調(diào)用,并且要保證同步塊或方法的鎖對象與調(diào)用wait和notify方法的對象是同一個,如此一來在調(diào)用wait之前當(dāng)前線程就已經(jīng)獲取某對象的鎖,執(zhí)行wait阻塞后當(dāng)前線程就將之前獲取的對象鎖釋放
wait/notify用例
8.Semaphore 是什么?
? ? ? ? Semaphore是一個計(jì)數(shù)信號,用來限流,它創(chuàng)建一個共享鎖,可以讓很多線程都拿到資源
semaphore.acquire()來進(jìn)行獲取資源,如果資源沒有了則進(jìn)行CLH同步隊(duì)列的入隊(duì)操作,這些都是基于AQS框架基礎(chǔ)上的
9.CountDownLatch原理
CountDownLatch這個類能夠使一個線程等待其他線程完成各自的工作后再執(zhí)行,例如我們打游戲,加載游戲,必須所有玩家都加載成功,才能進(jìn)入游戲.它首先創(chuàng)建一個計(jì)數(shù)器,每當(dāng)一個線程完成任務(wù)就調(diào)用countDownLatch.countDown()方法,減少計(jì)數(shù),最后調(diào)用countDownLatch.await()方法,等待所有線程都完成任務(wù)以后,才繼續(xù)執(zhí)行下面的任務(wù)
10.?CyclicBarrier 原理
柵欄屏障,但所有線程都到達(dá)了這個屏障(也叫同步點(diǎn))才繼續(xù)執(zhí)行下面的操作,和CountDownLatch類似,cyclicBarrier.await()方法對每個行程進(jìn)行阻塞
11.CountDownLatch和CyclicBarrier的區(qū)別
? ??????CyclicBarrier 可以重復(fù)使用,而 CountdownLatch 不能重復(fù)使用。
? ? ? ? CyclicBarrier必須等到所有線程都執(zhí)行完才行,不然會一直堵塞
