支持多線程編程是Java語言不同與其他語言的優(yōu)點(diǎn)。
1 :什么是線程厌漂?
? ? 在回答這個(gè)問題之前萨醒,先要了解什么是進(jìn)程。
? ? 進(jìn)程是程序在數(shù)據(jù)集合上的一次執(zhí)行過程桩卵,是資源申請验靡,調(diào)度和獨(dú)立運(yùn)行的單位。(現(xiàn)在是不是有點(diǎn)暈雏节,沒事胜嗓,舉個(gè)列子就理解了)比如:在電腦中你可以同時(shí)打開QQ,播放器等等應(yīng)用程序钩乍。實(shí)際在操作系統(tǒng)中就是創(chuàng)建了對應(yīng)的進(jìn)程辞州。對于單CPU的計(jì)算機(jī)來講,同一時(shí)刻只有一個(gè)進(jìn)程在運(yùn)作寥粹,不是全部運(yùn)作变过,它們是通過短時(shí)間的交替來運(yùn)行。時(shí)間比較短涝涤,所以就感覺是一塊執(zhí)行媚狰。
線程是進(jìn)程的基本單位。是一個(gè)獨(dú)立執(zhí)行線索阔拳,一個(gè)進(jìn)程最少包含一個(gè)線程崭孤。進(jìn)程執(zhí)行時(shí),真正起作用的是線程糊肠。線程又稱為輕量級進(jìn)程辨宠,它和進(jìn)程一樣擁有獨(dú)立的執(zhí)行控制,不一樣的是線程沒有獨(dú)立的存儲(chǔ)空間货裹,和所屬進(jìn)程中其他線程公用一個(gè)存儲(chǔ)空間嗤形。
2 : 線程的概念模型
? ? a:虛擬的CPU(封裝在java.lang.Thread類)
? ? b:CPU所執(zhí)行的代碼
? ? c:CPU所需要的變量
3:線程的創(chuàng)建
? ? 有兩種方式
? ? a:繼承Thread類。
? ? b:實(shí)現(xiàn)Runnable接口弧圆。
4 :Thread類中的主要方法
public Thread()——構(gòu)造方法赋兵,創(chuàng)建一個(gè)Thread對象,名字默認(rèn)為Thread-n搔预,根據(jù)創(chuàng)建的先后順序毡惜。n從0開始。
public Thread(String name)——構(gòu)造方法斯撮,創(chuàng)建一個(gè)名字為name的Thread對象
public Thread(Runnable target)——構(gòu)造方法经伙,創(chuàng)建一個(gè)新的實(shí)現(xiàn)Runnable接口的線程類,
public Thread(Runnable target ,String name)——構(gòu)造方法勿锅,創(chuàng)建一個(gè)新的實(shí)現(xiàn)了Runnable接口的線程類帕膜,同時(shí)設(shè)置名字為name
public long getId()——返回該線程的唯一ID
public void run()——線程體,此線程所有的代碼都在其中寫溢十。此方法不能被顯性調(diào)用垮刹,只能由JVM調(diào)用,調(diào)用線程的start()方法時(shí)张弛,JVM會(huì)調(diào)用run()方法荒典。
public void start()——調(diào)用此方法酪劫,JVM會(huì)調(diào)用run() 方法。
public void join()——當(dāng)前線程執(zhí)行某一線程的此方法寺董,當(dāng)前線程等到該線程執(zhí)行完后才能執(zhí)行
public static void slep(long mills)——線程休眠覆糟,休眠時(shí)間為mills,休眠時(shí)不釋放所占有的資源.
public static void yield()——暫停當(dāng)前正在執(zhí)行的線程對象遮咖,并執(zhí)行其他線程滩字。該線程直接進(jìn)入就緒狀態(tài)。
這是主要的幾個(gè)御吞,還有好多的方法參考javaAPI
這個(gè)例子是繼承Thread
這個(gè)例子是實(shí)現(xiàn)Runnable接口
(實(shí)現(xiàn)Runnable接口的類麦箍,稱為線程類,這個(gè)類是不能作為線程啟動(dòng)的陶珠,必須通過Thrad構(gòu)造方法進(jìn)行“深加工”后在可以挟裂。這個(gè)方法可以創(chuàng)造多個(gè)線程對象,但執(zhí)行的線程體都是一樣的揍诽。)
5 : 線程的狀態(tài)
? ? 三個(gè)階段
? ? a:新建(New)new 出一個(gè)新對象
? ? b: ? 就緒 (Runnable) ?新建狀態(tài)的對象調(diào)用start()方法话瞧,對象進(jìn)入就緒狀態(tài)。
? ? c:運(yùn)行 (Running) ?就緒狀態(tài)的對象寝姿,獲得CPU分配的時(shí)間片進(jìn)入運(yùn)行狀態(tài),處于運(yùn)行狀態(tài)的對象交排,可以通過不同的方式進(jìn)入不同的狀態(tài)。
? ? d: ? 阻塞 (Blocked)饵筑。阻塞分為三個(gè)狀態(tài) wait等待池阻塞(Blocked in object wait pool) lock等待池阻塞(Blocked in lock pool)和其他阻塞(Otherwise Blocked)
? ? e:死亡 (Dead)
狀態(tài)轉(zhuǎn)移具體如下????
? ? 1.處于運(yùn)行狀態(tài)的線程對象的run()或著main()方法結(jié)束后埃篓,線程就進(jìn)入死亡(程序運(yùn)行完成而運(yùn)行終止)狀態(tài)
? ? 2.處于運(yùn)行狀態(tài)的線程對象,當(dāng)線程對象調(diào)用了自身的sleep()方法或者其他的線程的jion()方法根资,或者發(fā)出I/O請求架专,就會(huì)進(jìn)入阻塞狀態(tài)(該狀態(tài)即停止當(dāng)前線程,但并不會(huì)釋放自己擁有的資源)當(dāng)sleep()結(jié)束或者jion()結(jié)束或者I/O操作結(jié)束后 或者 調(diào)用線程的interupt方法玄帕,該線程進(jìn)入就緒狀態(tài)部脚,繼續(xù)等待OS分配時(shí)間塊。
? ? 3.處于運(yùn)行狀態(tài)的線程對象裤纹,當(dāng)線程調(diào)用yield()方法委刘,放棄當(dāng)前獲得的CPU時(shí)間片,或者時(shí)間片用完線程還沒結(jié)束鹰椒,線程對象回到就緒狀態(tài)锡移,這時(shí)與其他進(jìn)程處于同一起跑線,OS可能會(huì)繼續(xù)讓他進(jìn)入運(yùn)行狀態(tài)漆际。
?4.當(dāng)線程對象剛進(jìn)入運(yùn)行狀態(tài)淆珊,但還沒運(yùn)行,發(fā)現(xiàn)線程運(yùn)行需要的資源被(synchronized)同步奸汇,并獲取不到鎖標(biāo)記施符,將會(huì)立即進(jìn)入阻塞(鎖等待池)狀態(tài)往声,登臺獲取鎖標(biāo)記,一旦線程獲得標(biāo)記戳吝,就進(jìn)入就緒狀態(tài)浩销,等待OS分配CPU時(shí)間片。
5.處于運(yùn)行狀態(tài)的線程對象骨坑,當(dāng)線程調(diào)用wait()方法后撼嗓,會(huì)進(jìn)入阻塞(等待隊(duì)列)狀態(tài)柬采,釋放它所占有的資源欢唾,這個(gè)狀態(tài)不能主動(dòng)喚醒,必須依靠其他線程調(diào)用notify()或者notifyAll()方法粉捻,才能被喚醒礁遣。由于notify只能喚醒一個(gè)線程,但不能確定具體喚醒的是哪一個(gè)線程肩刃,一般調(diào)用notifyAll()方法祟霍,線程喚醒后進(jìn)入鎖池,等待獲取鎖標(biāo)記盈包。