java多線(xiàn)程Thread的實(shí)現(xiàn)方法代碼詳解
之前有簡(jiǎn)單介紹過(guò)java多線(xiàn)程的使用,已經(jīng)Thread類(lèi)和Runnable類(lèi),為了更好地理解多線(xiàn)程,本文就Thread進(jìn)行詳細(xì)的分析。
start()
我們先來(lái)看看API中對(duì)于該方法的介紹:
使該線(xiàn)程開(kāi)始執(zhí)行;Java 虛擬機(jī)調(diào)用該線(xiàn)程的 run 方法。
結(jié)果是兩個(gè)線(xiàn)程并發(fā)地運(yùn)行;當(dāng)前線(xiàn)程(從調(diào)用返回給 start 方法)和另一個(gè)線(xiàn)程(執(zhí)行其 run 方法)。
多次啟動(dòng)一個(gè)線(xiàn)程是非法的。特別是當(dāng)線(xiàn)程已經(jīng)結(jié)束執(zhí)行后,不能再重新啟動(dòng)。
用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)行,一旦得到cpu時(shí)間片,就開(kāi)始執(zhí)行run()方法,這里方法 run()稱(chēng)為線(xiàn)程體,它包含了要執(zhí)行的這個(gè)線(xiàn)程的內(nèi)容,Run方法運(yùn)行結(jié)束,此線(xiàn)程隨即終止。
start方法是開(kāi)啟線(xiàn)程的方法,使用后java會(huì)創(chuàng)建一個(gè)新的線(xiàn)程執(zhí)行run里的方法。這是一個(gè)小demo:
for(int i=0;i<3;i++){
Thread t= new Thread(new Runnable() {
@Override
public void run() {
System.out.println(Thread.currentThread().getName()+" start");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+" end");
}
});
t.start();
}
System.out.println("it is over");
執(zhí)行結(jié)果:
it is over
Thread-1 start
Thread-0 start
Thread-2 start
Thread-0 end
Thread-1 end
Thread-2 end
由于多線(xiàn)程是有隨機(jī)性的,所以每次的結(jié)果可能都不一樣,這一點(diǎn)也是我們需要注意的,線(xiàn)程的執(zhí)行順序和調(diào)用順序并不一致。
run()
run方法就是調(diào)用Thread設(shè)置的Runnable的run方法,將上面的demo進(jìn)行修改:
for(int i=0;i<3;i++){
Thread t= new Thread(new Runnable() {
@Override
public void run() {
System.out.println(Thread.currentThread().getName()+" start");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+" end");
}
});
t.run();
}
System.out.println("it is over");
執(zhí)行結(jié)果:
main start
main end
main start
main end
main start
main end
it is over
run方法的直接結(jié)果和start有很大的差別,完全是按順序執(zhí)行,并沒(méi)有開(kāi)啟新線(xiàn)程。
stop()
stop方法是強(qiáng)制停止線(xiàn)程的執(zhí)行,是非安全的,不要使用此方法。在調(diào)用stop時(shí), 會(huì)對(duì)鎖定的資源進(jìn)行釋放,但這種釋放是非一致的,容易引起程序問(wèn)題。如果想要控制線(xiàn)程的停止,可以使用自定義變量來(lái)判斷或者isInterrupted()方法:
class Thread1 extends Thread {
@Override
public void run() {
//判斷線(xiàn)程體是否運(yùn)行
while (!isInterrupted()) {
// Do Something
}
}
}
interrupt()
interrupt的作用是通知線(xiàn)程,你已經(jīng)被中斷的,但具體的中斷執(zhí)行需要在線(xiàn)程自定義處理,甚至你可以不理會(huì)繼續(xù)執(zhí)行。具體的中孤單是會(huì)線(xiàn)程執(zhí)行join、wait、sleep方法時(shí),拋出InterruptedException。
Thread t1 = new Thread(new Runnable() {
@Override
public void run() {
System.out.println(Thread.currentThread().getName()+" start");
try {
for(int i=0;i<100000;i++){
System.out.println(i+"");
Thread.sleep(1);
}
} catch (InterruptedException e) {
System.out.println("the thread is interrupted");//可以在這里做資源釋放,日志記錄等
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+" end");
}
});
t1.start();
Thread.sleep(100);
t1.interrupt();
執(zhí)行結(jié)果:
65 66 67 68 the thread is interrupted java.lang.InterruptedException: sleep interrupted Thread-0 end at java.lang.Thread.sleep(Native Method) at com.wk.aqi.act.Test$1.run(Test.java:23) at java.lang.Thread.run(Thread.java:745)
isInterrupted()
判斷線(xiàn)程是否中斷,在執(zhí)行上面的interrupt方法后,會(huì)return true。
setPriority(int newPriority)和getPriority()
設(shè)置線(xiàn)程的優(yōu)先級(jí)和獲取線(xiàn)程的優(yōu)先級(jí),cpu分配的資源給側(cè)重給priority高的線(xiàn)程。
Thread t1 = new Thread(new Runnable() {
@Override
public void run() {
long t = System.currentTimeMillis();
System.out.println(Thread.currentThread().getName()+" start");
for(int i=0;i<1000;i++){
try {
Thread.sleep(1);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
System.out.println(Thread.currentThread().getName()+" t1 end "+(System.currentTimeMillis()-t));
}
});
Thread t2 = new Thread(new Runnable() {
@Override
public void run() {
long t = System.currentTimeMillis();
System.out.println(Thread.currentThread().getName()+" start");
for(int i=0;i<1000;i++){
try {
Thread.sleep(1);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
System.out.println(Thread.currentThread().getName()+" t2 end "+(System.currentTimeMillis()-t));
}
});
t1.setPriority(10);
t2.setPriority(1);
t2.start();
t1.start();
執(zhí)行結(jié)果:
Thread-0 start Thread-1 start Thread-0 t1 end 1357 Thread-1 t2 end 1371
在優(yōu)先級(jí)一樣的情況下,t1和t2是幾乎同時(shí)完成的,在優(yōu)先級(jí)不一樣的情況,有明顯的差別。
getName()
比較簡(jiǎn)單,獲取線(xiàn)程的名稱(chēng)。
join()和join(long millis)
jion方法的作用是等待線(xiàn)程執(zhí)行完成,join(long millis)可以設(shè)置最長(zhǎng)等待時(shí)間。比如主線(xiàn)程需要等待子線(xiàn)程完成,獲取子線(xiàn)程的結(jié)果后才能繼續(xù)往下執(zhí)行,這時(shí)候就可以使用join方法
Thread t1 = new Thread(new Runnable() {
@Override
public void run() {
long t = System.currentTimeMillis();
System.out.println(Thread.currentThread().getName()+" start");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+" t1 end "+(System.currentTimeMillis()-t));
}
});
t1.start();
t1.join();
System.out.println("等待t1執(zhí)行完,再執(zhí)行");
執(zhí)行結(jié)果:
Thread-0 start Thread-0 t1 end 1001 等待t1執(zhí)行完,再執(zhí)行
總結(jié)
以上就是本文關(guān)于java多線(xiàn)程Thread的實(shí)現(xiàn)方法代碼詳解的全部?jī)?nèi)容,希望對(duì)大家有所幫助。感興趣的朋友可以繼續(xù)參閱本站其他相關(guān)專(zhuān)題,如有不足之處,歡迎留言指出。
- Java多線(xiàn)程ThreadPoolExecutor詳解
- Java中使用Thread類(lèi)和Runnable接口實(shí)現(xiàn)多線(xiàn)程的區(qū)別
- Java多線(xiàn)程Thread類(lèi)的使用及注意事項(xiàng)
- Java超詳細(xì)講解多線(xiàn)程中的Process與Thread
- Java多線(xiàn)程 ThreadLocal原理解析
- Java多線(xiàn)程ThreadAPI詳細(xì)介紹
- Java使用Thread創(chuàng)建多線(xiàn)程并啟動(dòng)操作示例
- java 多線(xiàn)程Thread與runnable的區(qū)別
- Java多線(xiàn)程Thread類(lèi)的使用詳解
相關(guān)文章
反射機(jī)制:getDeclaredField和getField的區(qū)別說(shuō)明
這篇文章主要介紹了反射機(jī)制:getDeclaredField和getField的區(qū)別說(shuō)明,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-06-06
Java控制結(jié)構(gòu)知識(shí)點(diǎn)詳解
在本篇文章里小編給大家分享的是關(guān)于Java控制結(jié)構(gòu)知識(shí)點(diǎn)詳解,有需要的朋友們可以參考下。2019-10-10
spring mvc 和ajax異步交互完整實(shí)例代碼
本篇文章主要介紹了spring mvc 和ajax異步交互完整實(shí)例代碼,簡(jiǎn)單的AJAX+SpringMVC的異步交互小例子,有興趣的可以了解一下。2017-02-02
Springboot如何實(shí)現(xiàn)代理服務(wù)器
這篇文章主要介紹了Springboot如何實(shí)現(xiàn)代理服務(wù)器問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-06-06
Spring?Boot?+?Spring?Batch?實(shí)現(xiàn)批處理任務(wù)的詳細(xì)教程
這篇文章主要介紹了Spring?Boot+Spring?Batch實(shí)現(xiàn)批處理任務(wù),本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2023-08-08
java中BigDecimal的介紹及使用教程BigDecimal格式化及BigDecimal常見(jiàn)問(wèn)題
BigDecimal是Java在java.math包中提供的線(xiàn)程安全的API類(lèi),用來(lái)對(duì)超過(guò)16位有效位的數(shù)進(jìn)行精確的運(yùn)算,這篇文章主要介紹了java中BigDecimal的介紹及使用,BigDecimal格式化,BigDecimal常見(jiàn)問(wèn)題,需要的朋友可以參考下2023-08-08

