線程調度java
java自己實現了線程庫,也就是說java的線程並不和操作系統的線程對應,jvm在操作系統上面是一個進程,當這個進程被操作系統調度到後,jvm內部實現的線程庫再調度java線程,為什麼是這樣呢?考慮到以前的操作系統內核,比如linux,在以前都不直接支持線程,用戶線程和內核線程是多對一的關系,solaris一度也是這樣,所以java當然心有餘而力不足了,你操作系統都不能完美支持線程,你讓我實現不是難為我嗎?在那個年代,java多線程的調度完全是自主的,操作系統根本不知道java是多線程的,調度策略完全自己實現,單cpu下肯定是分時的,多cpu下就看jvm會不會建立多cpu上的多jvm實例了。
到了後來,操作系統內核紛紛都支持了多線程(windows開始就支持),那麼java也要考慮推卸一些責任了,這樣java線程就和操作系統線程一一對應或多多對應了,這個時候,如果是一一對應,那麼線程的調度完全交給了操作系統內核,當然jvm還保留一些策略足以影響到其內部的線程調度,舉個例子,在linux下,只要一個Thread.run就會調用一個fork產生一個線程。
問:java獲得cup使用權採用的搶占機制,使用cup的時候是分時機制,這句話對不對?
答:部分對,早期實現,基本可以實現搶占式,但是現代實現,如果系統不支持搶占,那麼jvm也無所謂搶佔了。
問:多線程使用cup和使用的操作系統有關還是java機制有關(xp是什麼機制)
答:早期是java機制實現,現在大部分是操作系統實現的,java機制僅僅保留了相關策略從而影響調度;xp是基於優先順序的搶占式調度,其性能很大程度依賴於動態優先順序提升
㈡ java線程池之ScheledThreadPoolExecutor實現原理
java中非同步周期任務調度有Timer,ScheledThreadPoolExecutor等實現,目前單機版的定時調度都是使用ScheledThreadPoolExecutor去實現,那麼它是如何實現周期執行任務的呢?其實它還是利用ThreadPoolExecutor線程池去執行任務,這一點從它是繼承自ThreadPoolExecutor救可以看的出來,其實關鍵在於如何實現任務的周期性調度,
ScheledThreadPoolExecutor類以及核心函數首先ScheledThreadPoolExecutor是實現ScheledExecutorService介面,它主要定義了四個方法:
周期調度一個Runnable的對象
周期調度一個Callable的對象
固定周期調度Runnable對象 (不管上一次Runnable執行結束的時間,總是以固定延遲時間執行 即 上一個Runnable執行開始時候 + 延時時間 = 下一個Runnable執行的時間點)
以固定延遲調度unnable對象(當上一個Runnable執行結束後+固定延遲 = 下一個Runnable執行的時間點)
{publicScheledFuture<?>schele(Runnablecommand,longdelay,TimeUnitunit);public<V>ScheledFuture<V>schele(Callable<V>callable,longdelay,TimeUnitunit);publicScheledFuture<?>scheleAtFixedRate(Runnablecommand,longinitialDelay,longperiod,TimeUnitunit);publicScheledFuture<?>scheleWithFixedDelay(Runnablecommand,longinitialDelay,longdelay,TimeUnitunit);}其次,ScheledThreadPoolExecutor是繼承ThreadPoolExecutor,所以它是藉助線程池的能力去執行任務,然後自身去實現周期性調度。從構造方法調用父類的線程池的構造方法,核心線程數是構造方法傳入,這里可以看到最大線程數是Integer的最大值即2147483647, 還有等待隊列是DelayedWorkQueue,它是實現延時的關鍵.
/***Createsanew{@codeScheledThreadPoolExecutor}withthe*givencorepoolsize.**@,even*iftheyareidle,unless{@codeallowCoreThreadTimeOut}isset*@{@codecorePoolSize<0}*/(intcorePoolSize){super(corePoolSize,Integer.MAX_VALUE,0,NANOSECONDS,newDelayedWorkQueue());}scheleAtFixedRate是實現周期性調度的方法,調度任務就是實現Runnable對象, 以及系統的開始延時時間,周期的調度的間隔時間。
計算初始觸發時間和執行周期,並和傳入的Runnable對象作為參數封裝成 ScheledFutureTask,然後調用decorateTask裝飾Tas(默認實現為空)。
設置ScheledFutureTask對象outerTask為t(默認就是它自己)。
調用delayedExecute延遲執行任務。
publicScheledFuture<?>scheleAtFixedRate(Runnablecommand,longinitialDelay,longperiod,**TimeUnitunit){if(command==null||unit==null)thrownewNullPointerException();if(period<=0)();ScheledFutureTask<Void>sft=newScheledFutureTask<Void>(command,null,triggerTime(initialDelay,unit),unit.toNanos(period));RunnableScheledFuture<Void>t=decorateTask(command,sft);sft.outerTask=t;delayedExecute(t);returnt;}判斷線程池狀態,如果不是處於running狀態,則拒絕該任務。
將該任務加入父類的延遲隊列(實際為初始化的DelayedWorkQueue對象)
再次判斷線程池不是處於running狀態,並且,判斷是否是處於shutdown狀態並且標志是否是true(默認是false,表示是否線程次處於shutdown狀態下是否繼續執行周期性任務),若果為true,則從隊列刪除任務,false,則確保啟動線程來執行周期性任務
privatevoiddelayedExecute(RunnableScheledFuture<?>task){if(isShutdown())reject(task);else{super.getQueue().add(task);if(isShutdown()&&!canRunInCurrentRunState(task.isPeriodic())&&remove(task))task.cancel(false);elseensurePrestart();}}獲取線程池數量
如果小於核心線程數,則啟動核心線程執行任務,如果線程數為空,則啟動非核心線程
voidensurePrestart(){intwc=workerCountOf(ctl.get());if(wc<corePoolSize)addWorker(null,true);elseif(wc==0)addWorker(null,false);}ScheledFutureTask的run函數獲取是否是周期性任務
判斷是否線程池狀態是否可以執行任務,如果為true,則取消任務 3 如果是非周期性任務,則直接調用父類FutureTask的run方法, 4 如果是周期性任務,則調用FutureTask的runAndReset函數, 如果該函數返回為true,則調用setNextRunTime設置下一次運行的時間, 並且還行reExecutePeriodic再次執行周期性任務。
publicvoidrun(){booleanperiodic=isPeriodic();if(!canRunInCurrentRunState(periodic))cancel(false);elseif(!periodic)ScheledFutureTask.super.run();elseif(ScheledFutureTask.super.runAndReset()){setNextRunTime();reExecutePeriodic(outerTask);}}判斷線程池是否處於可執行任務的狀態,如果為true,則重新將設置下一次運行時間的任務加入父類的等待隊列,
如果線程池處於不可運行任務的狀態,則並且從等待隊列中移除成功, 調用任務的取消操作,否則調用ensurePrestart確保啟動線程執行任務
voidreExecutePeriodic(RunnableScheledFuture<?>task){if(canRunInCurrentRunState(true)){super.getQueue().add(task);if(!canRunInCurrentRunState(true)&&remove(task))task.cancel(false);elseensurePrestart();}}DelayedWorkQueue類核心函數DelayedWorkQueue是繼承AbstractQueue,並實現BlockingQueue介面
<Runnable>implementsBlockingQueue<Runnable>{核心欄位
//初始容量為_CAPACITY=16;//等待隊列,只能保存RunnableScheledFuture對象privateRunnableScheledFuture<?>[]queue=newRunnableScheledFuture<?>[INITIAL_CAPACITY];//鎖privatefinalReentrantLocklock=newReentrantLock();//對俄大小privateintsize=0;//leader線程,表示最近需要執行的任務的線程。privateThreadleader=null;//條件鎖=lock.newCondition();offer函數:
將添加的參數轉換成RunnableScheledFuture對象。
加全局鎖。
獲取當前隊列的size,如果等於隊列的長度,則嗲用grow擴容,增加50%的數組長度。
size加1。
如果數組為0,則將加入的對象放在索引為0的位置,然後設置ScheledFutureTask的heapIndex的索引(便於後續快速刪除)。
調用siftUp做堆的上浮操作,這里是小根堆的操作。
如果隊列中第一個元素是傳入的對象,則將laader設置null
釋放鎖
返回true
publicbooleanoffer(Runnablex){if(x==null)thrownewNullPointerException();RunnableScheledFuture<?>e=(RunnableScheledFuture<?>)x;finalReentrantLocklock=this.lock;lock.lock();try{inti=size;if(i>=queue.length)grow();size=i+1;if(i==0){queue[0]=e;setIndex(e,0);}else{siftUp(i,e);}if(queue[0]==e){leader=null;available.signal();}}finally{lock.unlock();}returntrue;}siftUp主要就是做小根堆的上移操作,從if (key.compareTo(e) >= 0) 看出,如果key大於parent索引的元素,則停止。
/***Createsanew{@codeScheledThreadPoolExecutor}withthe*givencorepoolsize.**@,even*iftheyareidle,unless{@codeallowCoreThreadTimeOut}isset*@{@codecorePoolSize<0}*/(intcorePoolSize){super(corePoolSize,Integer.MAX_VALUE,0,NANOSECONDS,newDelayedWorkQueue());}0poll函數
加鎖
獲取隊列中索引為0的雲元素,若果為null或者第一個元素的執行時間戳時間大於當前時間則直接返回null,否則調用finishPoll將第一個元素返回.
釋放鎖
/***Createsanew{@codeScheledThreadPoolExecutor}withthe*givencorepoolsize.**@,even*iftheyareidle,unless{@codeallowCoreThreadTimeOut}isset*@{@codecorePoolSize<0}*/(intcorePoolSize){super(corePoolSize,Integer.MAX_VALUE,0,NANOSECONDS,newDelayedWorkQueue());}1將隊列size 減 1
獲取隊列中隊列中最後一個元素,並且設置隊列最後一個為null
最後一個元素不為null,則調用sfitdown進行,將最後一個元素設置到索引為0的位置,將下移操作,重新調整小根堆。
ScheledFutureTask的heapIndex為-1
/***Createsanew{@codeScheledThreadPoolExecutor}withthe*givencorepoolsize.**@,even*iftheyareidle,unless{@codeallowCoreThreadTimeOut}isset*@{@codecorePoolSize<0}*/(intcorePoolSize){super(corePoolSize,Integer.MAX_VALUE,0,NANOSECONDS,newDelayedWorkQueue());}2ScheledFutureTask的compareTo函數ScheledFutureTask實現compareTo方法邏輯
首先比較是否是同一個對象
若果是ScheledFutureTask對象,則比較time的大小,time是下一次執行的任務的時間戳,如果不是,則比較 getDelay的時間大小
/***Createsanew{@codeScheledThreadPoolExecutor}withthe*givencorepoolsize.**@,even*iftheyareidle,unless{@codeallowCoreThreadTimeOut}isset*@{@codecorePoolSize<0}*/(intcorePoolSize){super(corePoolSize,Integer.MAX_VALUE,0,NANOSECONDS,newDelayedWorkQueue());}3ScheledThreadPoolExecutor的take函數就是ThreadPoolExecutor的從任務隊列中獲取任務,沒有任務則一直等待(這里是線程數小於核心線程數的情況)
加可中斷鎖
獲取隊列中第一個元素的任務,從前面可以知道此任務執行的時間戳最小的任務
如果第一個任務為空,則再全局的鎖的條件鎖上等待,
如果第一個任務不為空,則獲取延遲時間,如果延時時間小於0,說明第一個任務已經到時間了,則返回第一個任務。
如果leader線程不為空,則讓線程在全局鎖的條件鎖上等待
如果leader為空,則將獲取第一個任務的當前線程賦值為leader變數。
在全局鎖的條件鎖上等待delay納秒, 等待結束後,如果當前線程還是等於leader線程,則重置leader為空
最後判斷 leader為空並且第一個任務不為空,則喚醒全局鎖上條件鎖的等待的線程。
釋放全局鎖。
/***Createsanew{@codeScheledThreadPoolExecutor}withthe*givencorepoolsize.**@,even*iftheyareidle,unless{@codeallowCoreThreadTimeOut}isset*@{@codecorePoolSize<0}*/(intcorePoolSize){super(corePoolSize,Integer.MAX_VALUE,0,NANOSECONDS,newDelayedWorkQueue());}4總結 綜合前面所述,線程池從DelayedWorkQueue每次取出的任務就是延遲時間最小的任務, 若果到達時間的任務,則執行任務,否則則用條件鎖Conditon的wait進行等待,執行完後,則用signal進行喚醒下一個任務的執行。
㈢ Java線程的知識要點
一、進程的概念
進程表示資源分配的基本單位,又是調度運行的基本單位。例如,用戶運行自攔念己的程序,系統就創建一個進程,並給它分配資源,包括內存空間、磁碟空間、I/O設備等。然後,把該進程放入就緒隊列。進程調度程序選中它,為它分配CPU以及其他有關的資源,該進程才真正運行。簡伍困所以,北京電腦培訓發現進程是系統中的並發執行的單位。
二、線程的概念
線程:(英語:thread)是操作系統能夠進行運算調度的最小單位。它被包含在進程之中,是進程中的實際運作單位。一條線程指的是進程中一個單一順序的控制流,一個進程中可以並發多個線程,每條線程並行執行不同的任務。
三、引用線程的優勢
(1)易於調度。
(2)提高並發性。通過線程可方便有效地實現並發性。進程可創建多個線程來執行同一程序的不同部分或相同部分。
(3)開銷少。創建線程比創建進程要快,所需開銷很少。
(4)利於充分發揮多處理器的功能。通過創建多線程進程(即一個進程可具有兩個或更多個線程),每個線程在一個處理器上運行,從而實現應用程序的並發性,使每個處理器都得到充分運行。
四、進程與線程的關系
(1)一個線程只能屬於一個進程,而一個進程可以有多個線程,但至少有一個線程。
(2)資源分配給進程,同一進程的所有線程共享該進程的所有資源。
(3)處理機分給線程,即真正在處理機上運行橘悉的是線程。
(4)線程在執行過程中,要協作同步。不同進程的線程間要利用消息通信的辦法實現同步。
簡單來說:
1、一個程序至少有一個進程,一個進程至少有一個線程。
2、進程在執行過程中擁有獨立的資源,而多個線程共享進程中的資源。
㈣ 鑳借В閲婁竴涓媕ava鐨勭嚎紼嬬殑浣跨敤
闅忕潃璁$畻鏈虹殑椋為熷彂灞曪紝涓浜鴻$畻鏈轟笂鐨勬搷浣滅郴緇熶篃綰風悍閲囩敤澶氫換鍔″拰鍒嗘椂璁捐★紝灝嗘棭鏈熷彧鏈夊ぇ鍨嬭$畻鏈烘墠鍏鋒湁鐨勭郴緇熺壒鎬у甫鍒頒簡涓浜鴻$畻鏈虹郴緇熶腑銆備竴鑸鍙浠ュ湪鍚屼竴鏃墮棿鍐呮墽琛屽氫釜紼嬪簭鐨勬搷浣滅郴緇熼兘鏈夎繘紼嬬殑姒傚康銆備竴涓榪涚▼灝辨槸涓涓鎵ц屼腑鐨勭▼搴忥紝鑰屾瘡涓涓榪涚▼閮芥湁鑷宸辯嫭絝嬬殑涓鍧楀唴瀛樼┖闂淬佷竴緇勭郴緇熻祫婧愩傚湪榪涚▼姒傚康涓錛屾瘡涓涓榪涚▼鐨勫唴閮ㄦ暟鎹鍜岀姸鎬侀兘鏄瀹屽叏鐙絝嬬殑銆侸ava紼嬪簭閫氳繃嫻佹帶鍒舵潵鎵ц岀▼搴忔祦錛岀▼搴忎腑鍗曚釜欏哄簭鐨勬祦鎺у埗縐頒負綰跨▼錛屽氱嚎紼嬪垯鎸囩殑鏄鍦ㄥ崟涓紼嬪簭涓鍙浠ュ悓鏃惰繍琛屽氫釜涓嶅悓鐨勭嚎紼嬶紝鎵ц屼笉鍚岀殑浠誨姟銆傚氱嚎紼嬫剰鍛崇潃涓涓紼嬪簭鐨勫氳岃鍙ュ彲浠ョ湅涓婂幓鍑犱箮鍦ㄥ悓涓鏃墮棿鍐呭悓鏃惰繍琛屻
綰跨▼涓庤繘紼嬬浉浼礆紝鏄涓孌靛畬鎴愭煇涓鐗瑰畾鍔熻兘鐨勪唬鐮侊紝鏄紼嬪簭涓鍗曚釜欏哄簭鐨勬祦鎺у埗錛涗絾涓庤繘紼嬩笉鍚岀殑鏄錛屽悓綾葷殑澶氫釜綰跨▼鏄鍏變韓涓鍧楀唴瀛樼┖闂村拰涓緇勭郴緇熻祫婧愶紝鑰岀嚎紼嬫湰韜鐨勬暟鎹閫氬父鍙鏈夊井澶勭悊鍣ㄧ殑瀵勫瓨鍣ㄦ暟鎹錛屼互鍙婁竴涓渚涚▼搴忔墽琛屾椂浣跨敤鐨勫爢鏍堛傛墍浠ョ郴緇熷湪浜х敓涓涓綰跨▼錛屾垨鑰呭湪鍚勪釜綰跨▼涔嬮棿鍒囨崲鏃訛紝璐熸媴瑕佹瘮榪涚▼灝忕殑澶氾紝姝e洜濡傛わ紝綰跨▼琚縐頒負杞昏礋鑽瘋繘紼嬶紙light-weight process錛夈備竴涓榪涚▼涓鍙浠ュ寘鍚澶氫釜綰跨▼銆
涓涓綰跨▼鏄涓涓紼嬪簭鍐呴儴鐨勯『搴忔帶鍒舵祦銆
1. 榪涚▼錛氭瘡涓榪涚▼閮芥湁鐙絝嬬殑浠g爜鍜屾暟鎹絀洪棿錛堣繘紼嬩笂涓嬫枃錛 錛岃繘紼嬪垏鎹㈢殑寮閿澶с
2. 綰跨▼錛氳交閲忕殑榪涚▼錛屽悓涓綾葷嚎紼嬪叡浜浠g爜鍜屾暟鎹絀洪棿錛屾瘡涓綰跨▼鏈夌嫭絝嬬殑榪愯屾爤鍜岀▼搴忚℃暟鍣錛圥C錛夛紝綰跨▼鍒囨崲鐨勫紑閿灝忋
3. 澶氳繘紼嬶細鍦ㄦ搷浣滅郴緇熶腑錛岃兘鍚屾椂榪愯屽氫釜浠誨姟紼嬪簭銆
4. 澶氱嚎紼嬶細鍦ㄥ悓涓搴旂敤紼嬪簭涓錛屾湁澶氫釜欏哄簭嫻佸悓鏃舵墽琛屻
6錛1錛1 綰跨▼鐨勬傚康妯″瀷
Java鍐呭湪鏀鎸佸氱嚎紼嬶紝瀹冪殑鎵鏈夌被閮芥槸鍦ㄥ氱嚎紼嬩笅瀹氫箟鐨勶紝Java鍒╃敤澶氱嚎紼嬩嬌鏁翠釜緋葷粺鎴愪負寮傛ョ郴緇熴侸ava涓鐨勭嚎紼嬬敱涓夐儴鍒嗙粍鎴愶紝濡傚浘6.1鎵紺恆
1. 鉶氭嫙鐨凜PU錛屽皝瑁呭湪Java.lang.Thread綾諱腑銆
2. CPU鎵鎵ц岀殑浠g爜錛屼紶閫掔粰Thread綾匯
3. CPU鎵澶勭悊鐨勬暟鎹錛屼紶閫掔粰Thread綾匯
鍥6.1綰跨▼
6. 1. 2 綰跨▼浣(1)
Java鐨勭嚎紼嬫槸閫氳繃Java.lang.Thread綾繪潵瀹炵幇鐨勩傚綋鎴戜滑鐢熸垚涓涓猅hread綾葷殑瀵硅薄涔嬪悗,涓涓鏂扮殑綰跨▼灝變駭鐢熶簡銆
姝ょ嚎紼嬪疄渚嬭〃紺篔ava瑙i噴鍣ㄤ腑鐨勭湡姝g殑綰跨▼錛岄氳繃瀹冨彲浠ュ惎鍔ㄧ嚎紼嬨佺粓姝㈢嚎紼嬨佺嚎紼嬫寕璧風瓑錛屾瘡涓綰跨▼閮芥槸閫氳繃綾籘hread鍦↗ava鐨勮蔣浠跺寘Java.lang涓瀹氫箟錛屽畠鐨勬瀯閫犳柟娉曚負錛
public Thread 錛圱hreadGroup group錛孯unnable target錛孲tring name錛夛紱
鍏朵腑錛実roup 鎸囨槑璇ョ嚎紼嬫墍灞炵殑綰跨▼緇勶紱target瀹為檯鎵ц岀嚎紼嬩綋鐨勭洰鏍囧硅薄錛屽畠蹇呴』瀹炵幇鎺ュ彛Runnable錛 name涓虹嚎紼嬪悕銆侸ava涓鐨勬瘡涓綰跨▼閮芥湁鑷宸辯殑鍚嶇О錛孞ava鎻愪緵浜嗕笉鍚孴hread綾繪瀯閫犲櫒錛屽厑璁哥粰綰跨▼鎸囧畾鍚嶇О銆傚傛灉name涓簄ull鏃訛紝鍒橨ava鑷鍔ㄦ彁渚涘敮涓鐨勫悕縐般
褰撲笂榪版瀯閫犳柟娉曠殑鏌愪釜鍙傛暟涓簄ull鏃訛紝鎴戜滑鍙寰楀埌涓嬮潰鐨勫嚑涓鏋勯犳柟娉曪細
public Thread 錛堬級錛
public Thread 錛圧unnable target錛夛紱
public Thread 錛圧unnable target錛孲tring name錛夛紱
public Thread 錛圫tring name錛夛紱
public Thread 錛圱hreadGroup group錛孯unnable target錛夛紱
public Thread 錛圱hreadGroup group錛孲tring name錛夛紱
涓涓綾誨0鏄庡疄鐜癛unnable鎺ュ彛灝卞彲浠ュ厖褰撶嚎紼嬩綋錛屽湪鎺ュ彛Runnable涓鍙瀹氫箟浜嗕竴涓鏂規硶 run錛堬級錛
public void run錛堬級錛
浠諱綍瀹炵幇鎺ュ彛Runnable鐨勫硅薄閮藉彲浠ヤ綔涓轟竴涓綰跨▼鐨勭洰鏍囧硅薄錛岀被Thread鏈韜涔熷疄鐜頒簡鎺ュ彛Runnable錛屽洜姝ゆ垜浠鍙浠ラ氳繃涓ょ嶆柟娉曞疄鐜扮嚎紼嬩綋銆
錛堜竴錛夊畾涔変竴涓綰跨▼綾伙紝瀹冪戶鎵跨嚎紼嬬被Thread騫墮噸鍐欏叾涓鐨勬柟娉 run錛堬級錛岃繖鏃跺湪鍒濆嬪寲榪欎釜綾葷殑瀹炰緥鏃訛紝鐩鏍噒arget鍙涓簄ull錛岃〃紺虹敱榪欎釜瀹炰緥瀵規潵鎵ц岀嚎紼嬩綋銆傜敱浜嶫ava鍙鏀鎸佸崟閲嶇戶鎵匡紝鐢ㄨ繖縐嶆柟娉曞畾涔夌殑綾諱笉鑳藉啀緇ф壙鍏跺畠鐖剁被銆
錛堜簩錛夋彁渚涗竴涓瀹炵幇鎺ュ彛Runnable鐨勭被浣滀負涓涓綰跨▼鐨勭洰鏍囧硅薄錛屽湪鍒濆嬪寲涓涓猅hread綾繪垨鑰匱hread瀛愮被鐨勭嚎紼嬪硅薄鏃訛紝鎶婄洰鏍囧硅薄浼犻掔粰榪欎釜綰跨▼瀹炰緥錛岀敱璇ョ洰鏍囧硅薄鎻愪緵綰跨▼浣 run錛堬級銆傝繖鏃訛紝瀹炵幇鎺ュ彛Runnable鐨勭被浠嶇劧鍙浠ョ戶鎵垮叾瀹冪埗綾匯
姣忎釜綰跨▼閮芥槸閫氳繃鏌愪釜鐗瑰畾Thread瀵硅薄鐨勬柟娉時un( )鏉ュ畬鎴愬叾鎿嶄綔鐨勶紝鏂規硶run( )縐頒負綰跨▼浣撱傚浘6.2琛ㄧず浜咼ava綰跨▼鐨勪笉鍚岀姸鎬佷互鍙婄姸鎬佷箣闂磋漿鎹㈡墍璋冪敤鐨勬柟娉曘
鍥6.2 綰跨▼鐨勭姸鎬
1. 鍒涘緩鐘舵(new Thread)
鎵ц屼笅鍒楄鍙ユ椂錛岀嚎紼嬪氨澶勪簬鍒涘緩鐘舵侊細
Thread myThread = new MyThreadClass( );
褰撲竴涓綰跨▼澶勪簬鍒涘緩鐘舵佹椂錛屽畠浠呬粎鏄涓涓絀虹殑綰跨▼瀵硅薄錛岀郴緇熶笉涓哄畠鍒嗛厤璧勬簮銆
2. 鍙榪愯岀姸鎬( Runnable )
Thread myThread = new MyThreadClass( );
myThread.start( );
褰撲竴涓綰跨▼澶勪簬鍙榪愯岀姸鎬佹椂錛岀郴緇熶負榪欎釜綰跨▼鍒嗛厤浜嗗畠闇鐨勭郴緇熻祫婧愶紝瀹夋帓鍏惰繍琛屽苟璋冪敤綰跨▼榪愯屾柟娉曪紝榪欐牱灝變嬌寰楄ョ嚎紼嬪勪簬鍙榪愯( Runnable )鐘舵併傞渶瑕佹敞鎰忕殑鏄榪欎竴鐘舵佸苟涓嶆槸榪愯屼腑鐘舵侊紙Running )錛屽洜涓虹嚎紼嬩篃璁稿疄闄呬笂騫舵湭鐪熸h繍琛屻傜敱浜庡緢澶氳$畻鏈洪兘鏄鍗曞勭悊鍣ㄧ殑錛屾墍浠ヨ佸湪鍚屼竴鏃跺埢榪愯屾墍鏈夌殑澶勪簬鍙榪愯岀姸鎬佺殑綰跨▼鏄涓嶅彲鑳界殑錛孞ava鐨勮繍琛岀郴緇熷繀欏誨疄鐜拌皟搴︽潵淇濊瘉榪欎簺綰跨▼鍏變韓澶勭悊鍣ㄣ
3. 涓嶅彲榪愯岀姸鎬侊紙Not Runnable錛
榪涘叆涓嶅彲榪愯岀姸鎬佺殑鍘熷洜鏈夊備笅鍑犳潯錛
1) 璋冪敤浜唖leep錛堬級鏂規硶;
2) 璋冪敤浜唖uspend錛堬級鏂規硶;
3) 涓虹瓑鍊欎竴涓鏉′歡鍙橀噺錛岀嚎紼嬭皟鐢╳ait錛堬級鏂規硶;
4) 杈撳叆杈撳嚭嫻佷腑鍙戠敓綰跨▼闃誨;
涓嶅彲榪愯岀姸鎬佷篃縐頒負闃誨炵姸鎬侊紙Blocked錛夈傚洜涓烘煇縐嶅師鍥狅紙杈撳叆/杈撳嚭銆佺瓑寰呮秷鎮鎴栧叾瀹冮樆濉炴儏鍐碉級錛岀郴緇熶笉鑳芥墽琛岀嚎紼嬬殑鐘舵併傝繖鏃跺嵆浣垮勭悊鍣ㄧ┖闂詫紝涔熶笉鑳芥墽琛岃ョ嚎紼嬨
4. 姝諱骸鐘舵侊紙Dead錛
綰跨▼鐨勭粓姝涓鑸鍙閫氳繃涓ょ嶆柟娉曞疄鐜幫細鑷鐒舵挙娑堬紙綰跨▼鎵ц屽畬錛夋垨鏄琚鍋滄錛堣皟鐢╯top()鏂規硶錛夈傜洰鍓嶄笉鎺ㄨ崘閫氳繃璋冪敤stop()鏉ョ粓姝㈢嚎紼嬬殑鎵ц岋紝鑰屾槸璁╃嚎紼嬫墽琛屽畬銆
http://www.bc-cn.net/Article/kfyy/java/jc/200410/83.html