////////////2016-11-15 ~ 2016-11-16///////////
int study_data(){
線程的概述(Introduction)
線程是一個(gè)程序的多個(gè)執(zhí)行路徑嗡呼,執(zhí)行調(diào)度的單位须肆,依托于進(jìn)程存在猛拴。 線程不僅可以共享進(jìn)程的內(nèi)存瘟忱,而且還擁有一個(gè)屬于自己的內(nèi)存空間,這段內(nèi)存空間也叫做線程棧手销,是在建立線程時(shí)由系統(tǒng)分配的歇僧,主要用來保存線程內(nèi)部所使用的數(shù)據(jù),如線程執(zhí)行函數(shù)中所定義的變量。
注意:Java中的多線程是一種搶占機(jī)制而不是分時(shí)機(jī)制诈悍。搶占機(jī)制指的是有多個(gè)線程處于可運(yùn)行狀態(tài)祸轮,但是只允許一個(gè)線程在運(yùn)行,他們通過競(jìng)爭(zhēng)的方式搶占CPU侥钳。
線程的定義(Defining)
1) 繼承java.lang.Thread類
public ?class ?Thread ?Test ?extends ?Thread {
? ? public ?void ?run() {
? ? ? ? ?System.out.println("I'm running!");
? ? }
}
2) 實(shí)現(xiàn)java.lang.Runnable接口
public? class? Thread? Test? implements? Runnable {
? ? public ?void ?run() {
? ? ? ? System.out.println("I'm running!");
? ? }
}
線程的啟動(dòng)(Starting)
1)如果線程是繼承Thread類适袜,則創(chuàng)建方式如下:
ThreadTest1 tt =new ThreadTest1();
tt.start();
2)如果是實(shí)現(xiàn)Runnable接口,則創(chuàng)建方式如下:
ThreadTest2 tt =new ThreadTest2();
Thread t =new Thread(tt);
t.start();
線程的狀態(tài)(State)
新生狀態(tài)(New): 當(dāng)一個(gè)線程的實(shí)例被創(chuàng)建即使用new關(guān)鍵字和Thread類或其子類創(chuàng)建一個(gè)線程對(duì)象后舷夺,此時(shí)該線程處于新生(new)狀態(tài)苦酱,處于新生狀態(tài)的線程有自己的內(nèi)存空間,但該線程并沒有運(yùn)行给猾,此時(shí)線程還不是活著的(not alive)疫萤;
就緒狀態(tài)(Runnable): 通過調(diào)用線程實(shí)例的start()方法來啟動(dòng)線程使線程進(jìn)入就緒狀態(tài)(runnable);處于就緒狀態(tài)的線程已經(jīng)具備了運(yùn)行條件敢伸,但還沒有被分配到CPU即不一定會(huì)被立即執(zhí)行扯饶,此時(shí)處于線程就緒隊(duì)列,等待系統(tǒng)為其分配CPCU池颈,等待狀態(tài)并不是執(zhí)行狀態(tài)帝际; 此時(shí)線程是活著的(alive);
運(yùn)行狀態(tài)(Running): 一旦獲取CPU(被JVM選中)饶辙,線程就進(jìn)入運(yùn)行(running)狀態(tài),線程的run()方法才開始被執(zhí)行斑粱;在運(yùn)行狀態(tài)的線程執(zhí)行自己的run()方法中的操作弃揽,直到調(diào)用其他的方法而終止、或者等待某種資源而阻塞则北、或者完成任務(wù)而死亡矿微;如果在給定的時(shí)間片內(nèi)沒有執(zhí)行結(jié)束,就會(huì)被系統(tǒng)給換下來回到線程的等待狀態(tài)尚揣;此時(shí)線程是活著的(alive)涌矢;
阻塞狀態(tài)(Blocked):通過調(diào)用join()、sleep()快骗、wait()或者資源被暫用使線程處于阻塞(blocked)狀態(tài)娜庇;處于Blocking狀態(tài)的線程仍然是活著的(alive)
死亡狀態(tài)(Dead):當(dāng)一個(gè)線程的run()方法運(yùn)行完畢或被中斷或被異常退出,該線程到達(dá)死亡(dead)狀態(tài)方篮。此時(shí)可能仍然存在一個(gè)該Thread的實(shí)例對(duì)象名秀,當(dāng)該Thread已經(jīng)不可能在被作為一個(gè)可被獨(dú)立執(zhí)行的線程對(duì)待了,線程的獨(dú)立的call stack已經(jīng)被dissolved藕溅。一旦某一線程進(jìn)入Dead狀態(tài)匕得,他就再也不能進(jìn)入一個(gè)獨(dú)立線程的生命周期了。對(duì)于一個(gè)處于Dead狀態(tài)的線程調(diào)用start()方法巾表,會(huì)出現(xiàn)一個(gè)運(yùn)行期(runtime exception)的異常汁掠;處于Dead狀態(tài)的線程不是活著的(not alive)略吨。
線程的方法(Method)、屬性(Property)
1)優(yōu)先級(jí)(priority)
thread.setPriority(int priority)
thread.getPriority(int priority)
每個(gè)類都有自己的優(yōu)先級(jí)考阱,一般property用1-10的整數(shù)表示翠忠,默認(rèn)優(yōu)先級(jí)是5,優(yōu)先級(jí)最高是10羔砾;優(yōu)先級(jí)高的線程并不一定比優(yōu)先級(jí)低的線程執(zhí)行的機(jī)會(huì)高负间,只是執(zhí)行的機(jī)率高;默認(rèn)一個(gè)線程的優(yōu)先級(jí)和創(chuàng)建他的線程優(yōu)先級(jí)相同姜凄;
2)Thread.sleep()/sleep(long millis)
當(dāng)前線程睡眠/millis的時(shí)間(millis指定睡眠時(shí)間是其最小的不執(zhí)行時(shí)間政溃,因?yàn)閟leep(millis)休眠到達(dá)后,無法保證會(huì)被JVM立即調(diào)度)态秧;sleep()是一個(gè)靜態(tài)方法(static method) 董虱,所以他不會(huì)停止其他的線程也處于休眠狀態(tài);線程sleep()時(shí)不會(huì)失去擁有的對(duì)象鎖申鱼。 作用:保持對(duì)象鎖愤诱,讓出CPU,調(diào)用目的是不讓當(dāng)前線程獨(dú)自霸占該進(jìn)程所獲取的CPU資源捐友,以留一定的時(shí)間給其他線程執(zhí)行的機(jī)會(huì)淫半;
3)Thread.yield()
讓出CPU的使用權(quán),給其他線程執(zhí)行機(jī)會(huì)匣砖、讓同等或以上優(yōu)先權(quán)的線程運(yùn)行(但并不保證當(dāng)前線程會(huì)被JVM再次調(diào)度科吭、使該線程重新進(jìn)入Running狀態(tài)),如果沒有同等或以上優(yōu)先權(quán)的線程猴鲫,那么yield()方法將不會(huì)起作用对人。
4)thread.join()
使用該方法的線程會(huì)在此之間執(zhí)行完畢后再往下繼續(xù)執(zhí)行之后的代碼。
5)object.wait()
當(dāng)一個(gè)線程執(zhí)行到wait()方法時(shí)拂共,他就進(jìn)入到一個(gè)和該對(duì)象相關(guān)的等待池(Waiting Pool)中牺弄,同時(shí)失去了對(duì)象的機(jī)鎖—暫時(shí)的,wait后還要返還對(duì)象鎖宜狐。當(dāng)前線程必須擁有當(dāng)前對(duì)象的鎖势告,如果當(dāng)前線程不是此鎖的擁有者,會(huì)拋出IllegalMonitorStateException異常,所以wait()必須在synchronized block中調(diào)用肌厨。
6)object.notify()/notifyAll()
喚醒在當(dāng)前對(duì)象等待池中等待的一個(gè)隨機(jī)線程/所有線程培慌。notify()/notifyAll()也必須擁有相同對(duì)象鎖,否則也會(huì)拋出IllegalMonitorStateException異常柑爸。
7)Synchronizing Block
synchronized這個(gè)關(guān)鍵字有兩種用法
1吵护、放方法名前形成同步方法;
public ?synchronized ?void ?test(){ }
2、放在塊前構(gòu)成同步塊馅而。
synchronized(this){ //塊 }
Synchronized Block/方法控制對(duì)類成員變量的訪問祥诽;Java中的每一個(gè)對(duì)象都有唯一的一個(gè)內(nèi)置的鎖,每個(gè)Synchronized Block/方法只有持有調(diào)用該方法被鎖定對(duì)象的鎖才可以訪問瓮恭,否則所屬線程阻塞雄坪;機(jī)鎖具有獨(dú)占性、一旦被一個(gè)Thread持有屯蹦,其他的Thread就不能再擁有(不能訪問其他同步方法)维哈,方法一旦執(zhí)行,就獨(dú)占該鎖登澜,直到從該方法返回時(shí)才將鎖釋放阔挠,此后被阻塞的線程方能獲得該鎖,重新進(jìn)入可執(zhí)行狀態(tài)脑蠕。
}