1、繼承Thread類(lèi)實(shí)現(xiàn)多線(xiàn)程
創(chuàng)新互聯(lián)服務(wù)項(xiàng)目包括漢南網(wǎng)站建設(shè)、漢南網(wǎng)站制作、漢南網(wǎng)頁(yè)制作以及漢南網(wǎng)絡(luò)營(yíng)銷(xiāo)策劃等。多年來(lái),我們專(zhuān)注于互聯(lián)網(wǎng)行業(yè),利用自身積累的技術(shù)優(yōu)勢(shì)、行業(yè)經(jīng)驗(yàn)、深度合作伙伴關(guān)系等,向廣大中小型企業(yè)、政府機(jī)構(gòu)等提供互聯(lián)網(wǎng)行業(yè)的解決方案,漢南網(wǎng)站推廣取得了明顯的社會(huì)效益與經(jīng)濟(jì)效益。目前,我們服務(wù)的客戶(hù)以成都為中心已經(jīng)輻射到漢南省份的部分城市,未來(lái)相信會(huì)繼續(xù)擴(kuò)大服務(wù)區(qū)域并繼續(xù)獲得客戶(hù)的支持與信任!
繼承Thread類(lèi)的方法盡管被我列為一種多線(xiàn)程實(shí)現(xiàn)方式,但Thread本質(zhì)上也是實(shí)現(xiàn)了Runnable接口的一個(gè)實(shí)例,它代表一個(gè)線(xiàn)程的實(shí)例,并且,啟動(dòng)線(xiàn)程的唯一方法就是通過(guò)Thread類(lèi)的start()實(shí)例方法。start()方法是一個(gè)native方法,它將啟動(dòng)一個(gè)新線(xiàn)程,并執(zhí)行run()方法。這種方式實(shí)現(xiàn)多線(xiàn)程很簡(jiǎn)單,通過(guò)自己的類(lèi)直接extend Thread,并復(fù)寫(xiě)run()方法,就可以啟動(dòng)新線(xiàn)程并執(zhí)行自己定義的run()方法。例如:
[java] view plain copy
public class MyThread extends Thread {
public void run() {
System.out.println("MyThread.run()");
}
}
在合適的地方啟動(dòng)線(xiàn)程如下:
[java] view plain copy
MyThread myThread1 = new MyThread();
MyThread myThread2 = new MyThread();
myThread1.start();
myThread2.start();
2、實(shí)現(xiàn)Runnable接口方式實(shí)現(xiàn)多線(xiàn)程
如果自己的類(lèi)已經(jīng)extends另一個(gè)類(lèi),就無(wú)法直接extends Thread,此時(shí),必須實(shí)現(xiàn)一個(gè)Runnable接口,如下:
[java] view plain copy
public class MyThread extends OtherClass implements Runnable {
public void run() {
System.out.println("MyThread.run()");
}
}
為了啟動(dòng)MyThread,需要首先實(shí)例化一個(gè)Thread,并傳入自己的MyThread實(shí)例:
[java] view plain copy
MyThread myThread = new MyThread();
Thread thread = new Thread(myThread);
thread.start();
事實(shí)上,當(dāng)傳入一個(gè)Runnable target參數(shù)給Thread后,Thread的run()方法就會(huì)調(diào)用target.run(),參考JDK源代碼:
[java] view plain copy
public void run() {
if (target != null) {
target.run();
}
}
3、使用ExecutorService、Callable、Future實(shí)現(xiàn)有返回結(jié)果的多線(xiàn)程
ExecutorService、Callable、Future這個(gè)對(duì)象實(shí)際上都是屬于Executor框架中的功能類(lèi)。想要詳細(xì)了解Executor框架的可以訪(fǎng)問(wèn) ,這里面對(duì)該框架做了很詳細(xì)的解釋。返回結(jié)果的線(xiàn)程是在JDK1.5中引入的新特征,確實(shí)很實(shí)用,有了這種特征我就不需要再為了得到返回值而大費(fèi)周折了,而且即便實(shí)現(xiàn)了也可能漏洞百出。
可返回值的任務(wù)必須實(shí)現(xiàn)Callable接口,類(lèi)似的,無(wú)返回值的任務(wù)必須Runnable接口。執(zhí)行Callable任務(wù)后,可以獲取一個(gè)Future的對(duì)象,在該對(duì)象上調(diào)用get就可以獲取到Callable任務(wù)返回的Object了,再結(jié)合線(xiàn)程池接口ExecutorService就可以實(shí)現(xiàn)傳說(shuō)中有返回結(jié)果的多線(xiàn)程了。下面提供了一個(gè)完整的有返回結(jié)果的多線(xiàn)程測(cè)試?yán)樱贘DK1.5下驗(yàn)證過(guò)沒(méi)問(wèn)題可以直接使用。
在Java語(yǔ)言產(chǎn)生前 傳統(tǒng)的程序設(shè)計(jì)語(yǔ)言的程序同一時(shí)刻只能單任務(wù)操作 效率非常低 例如程序往往在接收數(shù)據(jù)輸入時(shí)發(fā)生阻塞 只有等到程序獲得數(shù)據(jù)后才能繼續(xù)運(yùn)行 隨著Internet的迅猛發(fā)展 這種狀況越來(lái)越不能讓人們?nèi)淌?如果網(wǎng)絡(luò)接收數(shù)據(jù)阻塞 后臺(tái)程序就處于等待狀態(tài)而不繼續(xù)任何操作 而這種阻塞是經(jīng)常會(huì)碰到的 此時(shí)CPU資源被白白的閑置起來(lái) 如果在后臺(tái)程序中能夠同時(shí)處理多個(gè)任務(wù) 該多好?。?yīng)Internet技術(shù)而生的Java語(yǔ)言解決了這個(gè)問(wèn)題 多線(xiàn)程程序是Java語(yǔ)言的一個(gè)很重要的特點(diǎn) 在一個(gè)Java程序中 我們可以同時(shí)并行運(yùn)行多個(gè)相對(duì)獨(dú)立的線(xiàn)程 例如 我們?nèi)绻麆?chuàng)建一個(gè)線(xiàn)程來(lái)進(jìn)行數(shù)據(jù)輸入輸出 而創(chuàng)建另一個(gè)線(xiàn)程在后臺(tái)進(jìn)行其它的數(shù)據(jù)處理 如果輸入輸出線(xiàn)程在接收數(shù)據(jù)時(shí)阻塞 而處理數(shù)據(jù)的線(xiàn)程仍然在運(yùn)行 多線(xiàn)程程序設(shè)計(jì)大大提高了程序執(zhí)行效率和處理能力
線(xiàn)程的創(chuàng)建
我們知道Java是面向?qū)ο蟮某绦蛘Z(yǔ)言 用Java進(jìn)行程序設(shè)計(jì)就是設(shè)計(jì)和使用類(lèi) Java為我們提供了線(xiàn)程類(lèi)Thread來(lái)創(chuàng)建線(xiàn)程 創(chuàng)建線(xiàn)程與創(chuàng)建普通的類(lèi)的對(duì)象的操作是一樣的 而線(xiàn)程就是Thread類(lèi)或其子類(lèi)的實(shí)例對(duì)象 下面是一個(gè)創(chuàng)建啟動(dòng)一個(gè)線(xiàn)程的語(yǔ)句
Thread thread =new Thread(); file://聲明一個(gè)對(duì)象實(shí)例 即創(chuàng)建一個(gè)線(xiàn)程
Thread run(); file://用Thread類(lèi)中的run()方法啟動(dòng)線(xiàn)程
從這個(gè)例子 我們可以通過(guò)Thread()構(gòu)造方法創(chuàng)建一個(gè)線(xiàn)程 并啟動(dòng)該線(xiàn)程 事實(shí)上 啟動(dòng)線(xiàn)程 也就是啟動(dòng)線(xiàn)程的run()方法 而Thread類(lèi)中的run()方法沒(méi)有任何操作語(yǔ)句 所以這個(gè)線(xiàn)程沒(méi)有任何操作 要使線(xiàn)程實(shí)現(xiàn)預(yù)定功能 必須定義自己的run()方法 Java中通常有兩種方式定義run()方法
通過(guò)定義一個(gè)Thread類(lèi)的子類(lèi) 在該子類(lèi)中重寫(xiě)run()方法 Thread子類(lèi)的實(shí)例對(duì)象就是一個(gè)線(xiàn)程 顯然 該線(xiàn)程有我們自己設(shè)計(jì)的線(xiàn)程體run()方法 啟動(dòng)線(xiàn)程就啟動(dòng)了子類(lèi)中重寫(xiě)的run()方法
通過(guò)Runnable接口 在該接口中定義run()方法的接口 所謂接口跟類(lèi)非常類(lèi)似 主要用來(lái)實(shí)現(xiàn)特殊功能 如復(fù)雜關(guān)系的多重繼承功能 在此 我們定義一個(gè)實(shí)現(xiàn)Runnable() 接口的類(lèi) 在該類(lèi)中定義自己的run()方法 然后以該類(lèi)的實(shí)例對(duì)象為參數(shù)調(diào)用Thread類(lèi)的構(gòu)造方法來(lái)創(chuàng)建一個(gè)線(xiàn)程
線(xiàn)程被實(shí)際創(chuàng)建后處于待命狀態(tài) 激活(啟動(dòng))線(xiàn)程就是啟動(dòng)線(xiàn)程的run()方法 這是通過(guò)調(diào)用線(xiàn)程的start()方法來(lái)實(shí)現(xiàn)的
下面一個(gè)例子實(shí)踐了如何通過(guò)上述兩種方法創(chuàng)建線(xiàn)程并啟動(dòng)它們
// 通過(guò)Thread類(lèi)的子類(lèi)創(chuàng)建的線(xiàn)程 class thread extends Thread { file://自定義線(xiàn)程的run()方法 public void run() { System out println( Thread is running… ); } } file://通過(guò)Runnable接口創(chuàng)建的另外一個(gè)線(xiàn)程 class thread implements Runnable { file://自定義線(xiàn)程的run()方法 public void run() { System out println( Thread is running… ); } } file://程序的主類(lèi) class Multi_Thread file://聲明主類(lèi) { plubic static void mail(String args[]) file://聲明主方法 { thread threadone=new thread (); file://用Thread類(lèi)的子類(lèi)創(chuàng)建線(xiàn)程 Thread threado=new Thread(new thread ()); file://用Runnable接口類(lèi)的對(duì)象創(chuàng)建線(xiàn)程 threadone start(); threado start(); 方法啟動(dòng)線(xiàn)程 } }
運(yùn)行該程序就可以看出 線(xiàn)程threadone和threado交替占用CPU 處于并行運(yùn)行狀態(tài) 可以看出 啟動(dòng)線(xiàn)程的run()方法是通過(guò)調(diào)用線(xiàn)程的start()方法來(lái)實(shí)現(xiàn)的(見(jiàn)上例中主類(lèi)) 調(diào)用start()方法啟動(dòng)線(xiàn)程的run()方法不同于一般的調(diào)用方法 調(diào)用一般方法時(shí) 必須等到一般方法執(zhí)行完畢才能夠返回start()方法 而啟動(dòng)線(xiàn)程的run()方法后 start()告訴系統(tǒng)該線(xiàn)程準(zhǔn)備就緒可以啟動(dòng)run()方法后 就返回start()方法執(zhí)行調(diào)用start()方法語(yǔ)句下面的語(yǔ)句 這時(shí)run()方法可能還在運(yùn)行 這樣 線(xiàn)程的啟動(dòng)和運(yùn)行并行進(jìn)行 實(shí)現(xiàn)了多任務(wù)操作
線(xiàn)程的優(yōu)先級(jí)
對(duì)于多線(xiàn)程程序 每個(gè)線(xiàn)程的重要程度是不盡相同 如多個(gè)線(xiàn)程在等待獲得CPU時(shí)間時(shí) 往往我們需要優(yōu)先級(jí)高的線(xiàn)程優(yōu)先搶占到CPU時(shí)間得以執(zhí)行 又如多個(gè)線(xiàn)程交替執(zhí)行時(shí) 優(yōu)先級(jí)決定了級(jí)別高的線(xiàn)程得到CPU的次數(shù)多一些且時(shí)間多長(zhǎng)一些 這樣 高優(yōu)先級(jí)的線(xiàn)程處理的任務(wù)效率就高一些
Java中線(xiàn)程的優(yōu)先級(jí)從低到高以整數(shù) ~ 表示 共分為 級(jí) 設(shè)置優(yōu)先級(jí)是通過(guò)調(diào)用線(xiàn)程對(duì)象的setPriority()方法 如上例中 設(shè)置優(yōu)先級(jí)的語(yǔ)句為
thread threadone=new thread (); file://用Thread類(lèi)的子類(lèi)創(chuàng)建線(xiàn)程
Thread threado=new Thread(new thread ()); file://用Runnable接口類(lèi)的對(duì)象創(chuàng)建線(xiàn)程
threadone setPriority( ); file://設(shè)置threadone的優(yōu)先級(jí)
threado setPriority( ); file://設(shè)置threado的優(yōu)先級(jí)
threadone start(); threado start(); 方法啟動(dòng)線(xiàn)程
這樣 線(xiàn)程threadone將會(huì)優(yōu)先于線(xiàn)程threado執(zhí)行 并將占有更多的CPU時(shí)間 該例中 優(yōu)先級(jí)設(shè)置放在線(xiàn)程啟動(dòng)前 也可以在啟動(dòng)后進(jìn)行設(shè)置 以滿(mǎn)足不同的優(yōu)先級(jí)需求
線(xiàn)程的(同步)控制
一個(gè)Java程序的多線(xiàn)程之間可以共享數(shù)據(jù) 當(dāng)線(xiàn)程以異步方式訪(fǎng)問(wèn)共享數(shù)據(jù)時(shí) 有時(shí)候是不安全的或者不和邏輯的 比如 同一時(shí)刻一個(gè)線(xiàn)程在讀取數(shù)據(jù) 另外一個(gè)線(xiàn)程在處理數(shù)據(jù) 當(dāng)處理數(shù)據(jù)的線(xiàn)程沒(méi)有等到讀取數(shù)據(jù)的線(xiàn)程讀取完畢就去處理數(shù)據(jù) 必然得到錯(cuò)誤的處理結(jié)果 這和我們前面提到的讀取數(shù)據(jù)和處理數(shù)據(jù)并行多任務(wù)并不矛盾 這兒指的是處理數(shù)據(jù)的線(xiàn)程不能處理當(dāng)前還沒(méi)有讀取結(jié)束的數(shù)據(jù) 但是可以處理其它的數(shù)據(jù)
如果我們采用多線(xiàn)程同步控制機(jī)制 等到第一個(gè)線(xiàn)程讀取完數(shù)據(jù) 第二個(gè)線(xiàn)程才能處理該數(shù)據(jù) 就會(huì)避免錯(cuò)誤 可見(jiàn) 線(xiàn)程同步是多線(xiàn)程編程的一個(gè)相當(dāng)重要的技術(shù)
在講線(xiàn)程的同步控制前我們需要交代如下概念
用Java關(guān)鍵字synchonized同步對(duì)共享數(shù)據(jù)操作的方法
在一個(gè)對(duì)象中 用synchonized聲明的方法為同步方法 Java中有一個(gè)同步模型 監(jiān)視器 負(fù)責(zé)管理線(xiàn)程對(duì)對(duì)象中的同步方法的訪(fǎng)問(wèn) 它的原理是 賦予該對(duì)象唯一一把 鑰匙 當(dāng)多個(gè)線(xiàn)程進(jìn)入對(duì)象 只有取得該對(duì)象鑰匙的線(xiàn)程才可以訪(fǎng)問(wèn)同步方法 其它線(xiàn)程在該對(duì)象中等待 直到該線(xiàn)程用wait()方法放棄這把鑰匙 其它等待的線(xiàn)程搶占該鑰匙 搶占到鑰匙的線(xiàn)程后才可得以執(zhí)行 而沒(méi)有取得鑰匙的線(xiàn)程仍被阻塞在該對(duì)象中等待
file://聲明同步的一種方式 將方法聲明同步
class store {public synchonized void store_in(){… }public synchonized void store_out(){ … }}
利用wait() notify()及notifyAll()方法發(fā)送消息實(shí)現(xiàn)線(xiàn)程間的相互聯(lián)系
Java程序中多個(gè)線(xiàn)程通過(guò)消息來(lái)實(shí)現(xiàn)互動(dòng)聯(lián)系的 這幾種方法實(shí)現(xiàn)了線(xiàn)程間的消息發(fā)送 例如定義一個(gè)對(duì)象的synchonized 方法 同一時(shí)刻只能夠有一個(gè)線(xiàn)程訪(fǎng)問(wèn)該對(duì)象中的同步方法 其它線(xiàn)程被阻塞 通??梢杂胣otify()或notifyAll()方法喚醒其它一個(gè)或所有線(xiàn)程 而使用wait()方法來(lái)使該線(xiàn)程處于阻塞狀態(tài) 等待其它的線(xiàn)程用notify()喚醒
一個(gè)實(shí)際的例子就是生產(chǎn)和銷(xiāo)售 生產(chǎn)單元將產(chǎn)品生產(chǎn)出來(lái)放在倉(cāng)庫(kù)中 銷(xiāo)售單元?jiǎng)t從倉(cāng)庫(kù)中提走產(chǎn)品 在這個(gè)過(guò)程中 銷(xiāo)售單元必須在倉(cāng)庫(kù)中有產(chǎn)品時(shí)才能提貨 如果倉(cāng)庫(kù)中沒(méi)有產(chǎn)品 則銷(xiāo)售單元必須等待
程序中 假如我們定義一個(gè)倉(cāng)庫(kù)類(lèi)store 該類(lèi)的實(shí)例對(duì)象就相當(dāng)于倉(cāng)庫(kù) 在store類(lèi)中定義兩個(gè)成員方法 store_in() 用來(lái)模擬產(chǎn)品制造者往倉(cāng)庫(kù)中添加產(chǎn)品 strore_out()方法則用來(lái)模擬銷(xiāo)售者從倉(cāng)庫(kù)中取走產(chǎn)品 然后定義兩個(gè)線(xiàn)程類(lèi) customer類(lèi) 其中的run()方法通過(guò)調(diào)用倉(cāng)庫(kù)類(lèi)中的store_out()從倉(cāng)庫(kù)中取走產(chǎn)品 模擬銷(xiāo)售者 另外一個(gè)線(xiàn)程類(lèi)producer中的run()方法通過(guò)調(diào)用倉(cāng)庫(kù)類(lèi)中的store_in()方法向倉(cāng)庫(kù)添加產(chǎn)品 模擬產(chǎn)品制造者 在主類(lèi)中創(chuàng)建并啟動(dòng)線(xiàn)程 實(shí)現(xiàn)向倉(cāng)庫(kù)中添加產(chǎn)品或取走產(chǎn)品
如果倉(cāng)庫(kù)類(lèi)中的store_in() 和store_out()方法不聲明同步 這就是個(gè)一般的多線(xiàn)程 我們知道 一個(gè)程序中的多線(xiàn)程是交替執(zhí)行的 運(yùn)行也是無(wú)序的 這樣 就可能存在這樣的問(wèn)題
倉(cāng)庫(kù)中沒(méi)有產(chǎn)品了 銷(xiāo)售者還在不斷光顧 而且還不停的在 取 產(chǎn)品 這在現(xiàn)實(shí)中是不可思義的 在程序中就表現(xiàn)為負(fù)值 如果將倉(cāng)庫(kù)類(lèi)中的stroe_in()和store_out()方法聲明同步 如上例所示 就控制了同一時(shí)刻只能有一個(gè)線(xiàn)程訪(fǎng)問(wèn)倉(cāng)庫(kù)對(duì)象中的同步方法 即一個(gè)生產(chǎn)類(lèi)線(xiàn)程訪(fǎng)問(wèn)被聲明為同步的store_in()方法時(shí) 其它線(xiàn)程將不能夠訪(fǎng)問(wèn)對(duì)象中的store_out()同步方法 當(dāng)然也不能訪(fǎng)問(wèn)store_in()方法 必須等到該線(xiàn)程調(diào)用wait()方法放棄鑰匙 其它線(xiàn)程才有機(jī)會(huì)訪(fǎng)問(wèn)同步方法
lishixinzhi/Article/program/Java/gj/201311/27301
public class RunThread implements Runnable{
String name;
Thread runner;
static boolean bool=true;
public RunThread(String threadName) {
name=threadName;
}
public void onStart()
{
runner = new Thread(this);
runner.setName(name);
runner.start();
}
public void run() {
String name=Thread.currentThread().getName();
System.out.println(name + " 線(xiàn)程運(yùn)行開(kāi)始!");
int index=0;
if(name.equals("小寫(xiě)字母"))
index='a';
else if(name.equals("大寫(xiě)字母"))
index='A';
while(!bool);
bool=false;
for(int i=index;i26+index;i++)
System.out.print((char)i+" ");
System.out.println();
bool=true;
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(name + " 線(xiàn)程運(yùn)行結(jié)束!");
}
public static void main(String[] args) {
RunThread a=new RunThread("小寫(xiě)字母");
RunThread b=new RunThread("大寫(xiě)字母");
a.onStart();
b.onStart();
//System.out.println(" 線(xiàn)程運(yùn)行開(kāi)始!");
}
1、 認(rèn)識(shí)Thread和Runnable
Java中實(shí)現(xiàn)多線(xiàn)程有兩種途徑:繼承Thread類(lèi)或者實(shí)現(xiàn)Runnable接口。Runnable是接口,建議用接口的方式生成線(xiàn)程,因?yàn)榻涌诳梢詫?shí)現(xiàn)多繼承,況且Runnable只有一個(gè)run方法,很適合繼承。在使用Thread的時(shí)候只需繼承Thread,并且new一個(gè)實(shí)例出來(lái),調(diào)用start()方法即可以啟動(dòng)一個(gè)線(xiàn)程。
Thread Test = new Thread();
Test.start();
在使用Runnable的時(shí)候需要先new一個(gè)實(shí)現(xiàn)Runnable的實(shí)例,之后啟動(dòng)Thread即可。
Test impelements Runnable;
Test t = new Test();
Thread test = new Thread(t);
test.start();
總結(jié):Thread和Runnable是實(shí)現(xiàn)java多線(xiàn)程的2種方式,runable是接口,thread是類(lèi),建議使用runable實(shí)現(xiàn)java多線(xiàn)程,不管如何,最終都需要通過(guò)thread.start()來(lái)使線(xiàn)程處于可運(yùn)行狀態(tài)。
2、 認(rèn)識(shí)Thread的start和run
1) start:
用start方法來(lái)啟動(dòng)線(xiàn)程,真正實(shí)現(xiàn)了多線(xiàn)程運(yùn)行,這時(shí)無(wú)需等待run方法體代碼執(zhí)行完畢而直接繼續(xù)執(zhí)行下面的代碼。通過(guò)調(diào)用Thread類(lèi)的start()方法來(lái)啟動(dòng)一個(gè)線(xiàn)程,這時(shí)此線(xiàn)程處于就緒(可運(yùn)行)狀態(tài),并沒(méi)有運(yùn)行,一旦得到spu時(shí)間片,就開(kāi)始執(zhí)行run()方法,這里方法run()稱(chēng)為線(xiàn)程體,它包含了要執(zhí)行的這個(gè)線(xiàn)程的內(nèi)容,Run方法運(yùn)行結(jié)束,此線(xiàn)程隨即終止。
2) run:
run()方法只是類(lèi)的一個(gè)普通方法而已,如果直接調(diào)用Run方法,程序中依然只有主線(xiàn)程這一個(gè)線(xiàn)程,其程序執(zhí)行路徑還是只有一條,還是要順序執(zhí)行,還是要等待run方法體執(zhí)行完畢后才可繼續(xù)執(zhí)行下面的代碼,這樣就沒(méi)有達(dá)到寫(xiě)線(xiàn)程的目的。
總結(jié):調(diào)用start方法方可啟動(dòng)線(xiàn)程,而run方法只是thread的一個(gè)普通方法調(diào)用,還是在主線(xiàn)程里執(zhí)行。
3、 線(xiàn)程狀態(tài)說(shuō)明
線(xiàn)程狀態(tài)從大的方面來(lái)說(shuō),可歸結(jié)為:初始狀態(tài)、可運(yùn)行狀態(tài)、不可運(yùn)行狀態(tài)和消亡狀態(tài),具體可細(xì)分為上圖所示7個(gè)狀態(tài),說(shuō)明如下:
1) 線(xiàn)程的實(shí)現(xiàn)有兩種方式,一是繼承Thread類(lèi),二是實(shí)現(xiàn)Runnable接口,但不管怎樣,當(dāng)我們new了thread實(shí)例后,線(xiàn)程就進(jìn)入了初始狀態(tài);
2) 當(dāng)該對(duì)象調(diào)用了start()方法,就進(jìn)入可運(yùn)行狀態(tài);
3) 進(jìn)入可運(yùn)行狀態(tài)后,當(dāng)該對(duì)象被操作系統(tǒng)選中,獲得CPU時(shí)間片就會(huì)進(jìn)入運(yùn)行狀態(tài);
4) 進(jìn)入運(yùn)行狀態(tài)后case就比較多,大致有如下情形:
·run()方法或main()方法結(jié)束后,線(xiàn)程就進(jìn)入終止?fàn)顟B(tài);
·當(dāng)線(xiàn)程調(diào)用了自身的sleep()方法或其他線(xiàn)程的join()方法,就會(huì)進(jìn)入阻塞狀態(tài)(該狀態(tài)既停止當(dāng)前線(xiàn)程,但并不釋放所占有的資源)。當(dāng)sleep()結(jié)束或join()結(jié)束后,該線(xiàn)程進(jìn)入可運(yùn)行狀態(tài),繼續(xù)等待OS分配時(shí)間片;
·當(dāng)線(xiàn)程剛進(jìn)入可運(yùn)行狀態(tài)(注意,還沒(méi)運(yùn)行),發(fā)現(xiàn)將要調(diào)用的資源被鎖牢(synchroniza,lock),將會(huì)立即進(jìn)入鎖池狀態(tài),等待獲取鎖標(biāo)記(這時(shí)的鎖池里也許已經(jīng)有了其他線(xiàn)程在等待獲取鎖標(biāo)記,這時(shí)它們處于隊(duì)列狀態(tài),既先到先得),一旦線(xiàn)程獲得鎖標(biāo)記后,就轉(zhuǎn)入可運(yùn)行狀態(tài),等待OS分配CPU時(shí)間片;
·當(dāng)線(xiàn)程調(diào)用wait()方法后會(huì)進(jìn)入等待隊(duì)列(進(jìn)入這個(gè)狀態(tài)會(huì)釋放所占有的所有資源,與阻塞狀態(tài)不同),進(jìn)入這個(gè)狀態(tài)后,是不能自動(dòng)喚醒的,必須依靠其他線(xiàn)程調(diào)用notify()或notifyAll()方法才能被喚醒(由于notify()只是喚醒一個(gè)線(xiàn)程,但我們由不能確定具體喚醒的是哪一個(gè)線(xiàn)程,也許我們需要喚醒的線(xiàn)程不能夠被喚醒,因此在實(shí)際使用時(shí),一般都用notifyAll()方法,喚醒有所線(xiàn)程),線(xiàn)程被喚醒后會(huì)進(jìn)入鎖池,等待獲取鎖標(biāo)記。
·當(dāng)線(xiàn)程調(diào)用stop方法,即可使線(xiàn)程進(jìn)入消亡狀態(tài),但是由于stop方法是不安全的,不鼓勵(lì)使用,大家可以通過(guò)run方法里的條件變通實(shí)現(xiàn)線(xiàn)程的stop。
分享標(biāo)題:java中實(shí)現(xiàn)多線(xiàn)程代碼 java實(shí)現(xiàn)多線(xiàn)程方法
當(dāng)前地址:http://jinyejixie.com/article20/ddccico.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供Google、靜態(tài)網(wǎng)站、網(wǎng)站制作、搜索引擎優(yōu)化、微信小程序、標(biāo)簽優(yōu)化
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶(hù)投稿、用戶(hù)轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀(guān)點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話(huà):028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)
猜你還喜歡下面的內(nèi)容