java線(xiàn)程的基礎(chǔ)實(shí)例解析
java中建立線(xiàn)程可以有兩種方式,分別是繼承Thread類(lèi)和實(shí)現(xiàn)Runnable接口。
繼承Thread
public class MyThread extends Thread{
public MyThread(String name){
super(name);
}
int i;
public void run(){
for(i=0;i<5;i++){
System.out.println(getName()+"--"+i);
}
}
public static void main(String[] agrs){
new MyThread("線(xiàn)程1").start();
new MyThread("線(xiàn)程2").start();
}
}
/*
線(xiàn)程1--0
線(xiàn)程1--1
線(xiàn)程1--2
線(xiàn)程1--3
線(xiàn)程1--4
線(xiàn)程2--0
線(xiàn)程2--1
線(xiàn)程2--2
線(xiàn)程2--3
線(xiàn)程2--4
*/
如上,java中的線(xiàn)程對(duì)象必須一個(gè)類(lèi)的形式創(chuàng)建,而該類(lèi)中必須重寫(xiě)基類(lèi)的run()方法,該方法其實(shí)就是線(xiàn)程的執(zhí)行體。調(diào)用該類(lèi)實(shí)例的start方法則就隱式的調(diào)用了run方法。
不難看出,由于new了2次MyThread,所以?xún)纱蔚膶?shí)例是不同的,即各自都有各自的i變量,相互獨(dú)立。
Runnable接口
public class MyRunnable implements Runnable{
int i;
public void run(){
for(i=0;i<50;i++){
System.out.println(Thread.currentThread().getName()+"--"+i);//不能直接this.getName()
}
}
public static void main(String[] agrs){
MyRunnable myRun=new MyRunnable();
new Thread(myRun,"線(xiàn)程1").start();
new Thread(myRun,"線(xiàn)程2").start();
}
}
/*
線(xiàn)程1--0
線(xiàn)程1--1
線(xiàn)程2--0
線(xiàn)程2--3
線(xiàn)程2--4
線(xiàn)程2--5
線(xiàn)程2--6
線(xiàn)程2--7
線(xiàn)程2--8
線(xiàn)程2--9
線(xiàn)程2--10
線(xiàn)程2--11
線(xiàn)程2--12
線(xiàn)程2--13
線(xiàn)程2--14
線(xiàn)程2--15
線(xiàn)程1--2
線(xiàn)程2--16
線(xiàn)程2--18
線(xiàn)程2--19
線(xiàn)程2--20
線(xiàn)程2--21
線(xiàn)程2--22
線(xiàn)程2--23
線(xiàn)程2--24
線(xiàn)程1--17
線(xiàn)程2--25
線(xiàn)程1--26
線(xiàn)程2--27
線(xiàn)程1--28
線(xiàn)程1--30
線(xiàn)程2--29
線(xiàn)程1--31
線(xiàn)程2--32
線(xiàn)程2--34
線(xiàn)程2--35
線(xiàn)程2--36
線(xiàn)程2--37
線(xiàn)程1--33
線(xiàn)程2--38
線(xiàn)程1--39
線(xiàn)程1--41
線(xiàn)程2--40
線(xiàn)程1--42
線(xiàn)程1--44
線(xiàn)程1--45
線(xiàn)程2--43
線(xiàn)程1--46
線(xiàn)程2--47
線(xiàn)程2--49
線(xiàn)程1--48
*/
可以看出,由于實(shí)現(xiàn)這種方式是將某一個(gè)對(duì)象做為target加載到Thread類(lèi)上,所以即使new再多的Thread對(duì)象,只要target是同一引用的對(duì)象,則就調(diào)用該對(duì)象的run方法,所有線(xiàn)程均共享該target對(duì)象的資源,所以會(huì)看到線(xiàn)程1和線(xiàn)程2一共輸出了51次,2條線(xiàn)程共同完成了i從0到49的輸出,而并不像上面那樣分別輸出5次。至于為什么輸出了51條,兩條線(xiàn)程幾乎在同一時(shí)刻進(jìn)入就緒狀態(tài)(start方法只是讓線(xiàn)程進(jìn)入就緒狀態(tài)),觀(guān)察上面的i變量不難發(fā)現(xiàn)當(dāng)i等于0時(shí),此時(shí)線(xiàn)程1和線(xiàn)程2均同時(shí)處于運(yùn)行狀態(tài),產(chǎn)生了并發(fā)現(xiàn)象,共同輸出了i=0,而此之后CPU通過(guò)不斷的切換線(xiàn)程,使得在同一時(shí)刻只有一條線(xiàn)程在輸出。
線(xiàn)程狀態(tài)
線(xiàn)程分為4個(gè)狀態(tài)
就緒狀態(tài):調(diào)用start方法則進(jìn)入就緒狀態(tài)。
運(yùn)行狀態(tài):處于就緒狀態(tài)的線(xiàn)程會(huì)被jvm進(jìn)行調(diào)度從而成為運(yùn)行狀態(tài)。
阻塞狀態(tài):如有某些同步方法未返回結(jié)果則出現(xiàn)阻塞狀態(tài),或sleep和yeild。
死亡狀態(tài):方法體執(zhí)行完畢或者強(qiáng)行stop某個(gè)線(xiàn)程。
線(xiàn)程的基本操作
join()合并線(xiàn)程:當(dāng)前線(xiàn)程調(diào)用某線(xiàn)程的join方法后將會(huì)等待某線(xiàn)程執(zhí)行完畢后本線(xiàn)程才會(huì)繼續(xù)。
sleep(long milliseconds)線(xiàn)程睡眠:阻塞當(dāng)前線(xiàn)程,只有阻塞的時(shí)間到了才會(huì)繼續(xù)下去。再阻塞的同時(shí),會(huì)將CPU占有權(quán)交給其他線(xiàn)程,所以常常利用sleep(1)來(lái)切換線(xiàn)程。
**yield()線(xiàn)程讓步:**yeild類(lèi)似與sleep,但是它只會(huì)讓步于比自己級(jí)別高或者同級(jí)別的其他線(xiàn)程,若沒(méi)有其他線(xiàn)程均比自己級(jí)別低則再次執(zhí)行本線(xiàn)程。
后臺(tái)線(xiàn)程
一個(gè)程序被操作系統(tǒng)執(zhí)行后將有一個(gè)進(jìn)程,一個(gè)進(jìn)程至少有一個(gè)線(xiàn)程(主線(xiàn)程),主線(xiàn)程并沒(méi)有比其他線(xiàn)程有太多的特殊之處,只因?yàn)樗亲钤绫粓?zhí)行的線(xiàn)程,在主線(xiàn)程中將會(huì)創(chuàng)建其他線(xiàn)程,若不指明則默認(rèn)創(chuàng)建的是前臺(tái)線(xiàn)程(包括main線(xiàn)程),若調(diào)用setDaemon(true)則顯式的將該線(xiàn)程設(shè)置為后臺(tái)線(xiàn)程,后臺(tái)線(xiàn)程為Daemon線(xiàn)程,從名字就能看出,它的主要作用是為其他線(xiàn)程提供守護(hù),服務(wù)的功能。當(dāng)所有前臺(tái)線(xiàn)程結(jié)束后,后臺(tái)線(xiàn)程將會(huì)被強(qiáng)制結(jié)束,因?yàn)樗藭r(shí)已經(jīng)沒(méi)有存在的意義了。
前臺(tái)線(xiàn)程
public class ForeAndBackThread extends Thread{
public ForeAndBackThread(String name){
super(name);
}
public void run(){
int i;
for(i=0;i<9999;i++){
System.out.println(this.getName()+"--"+i);
}
}
public static void main(String[] args){
ForeAndBackThread th=new ForeAndBackThread("線(xiàn)程A");
//th.setDaemon(true);
th.start();
int j;
for(j=0;j<3;j++){
System.out.println(Thread.currentThread().getName()+"--"+j);
}
}
}
程序完整的輸出子線(xiàn)程中0到9998;說(shuō)明主線(xiàn)程并沒(méi)有什么特殊的,它的結(jié)束并不會(huì)影響其他前臺(tái)線(xiàn)程的運(yùn)行。
后臺(tái)線(xiàn)程
public class ForeAndBackThread extends Thread{
public ForeAndBackThread(String name){
super(name);
}
public void run(){
int i;
for(i=0;i<9999;i++){
System.out.println(this.getName()+"--"+i);
}
}
public static void main(String[] args){
ForeAndBackThread th=new ForeAndBackThread("線(xiàn)程A");
th.setDaemon(true);
th.start();
int j;
for(j=0;j<3;j++){
System.out.println(Thread.currentThread().getName()+"--"+j);
}
}
}
程序并不能完整的輸出0-9998就退出了,說(shuō)明前臺(tái)主線(xiàn)程結(jié)束后,jvm強(qiáng)制結(jié)束了后臺(tái)線(xiàn)程。
總結(jié)
以上就是本文關(guān)于java線(xiàn)程的基礎(chǔ)實(shí)例解析的全部?jī)?nèi)容,希望對(duì)大家有所幫助。感興趣的朋友可以繼續(xù)參閱本站其他相關(guān)專(zhuān)題,如有不足之處,歡迎留言指出。感謝朋友們對(duì)本站的支持!
相關(guān)文章
詳解jdbc實(shí)現(xiàn)對(duì)CLOB和BLOB數(shù)據(jù)類(lèi)型的操作
這篇文章主要介紹了詳解jdbc實(shí)現(xiàn)對(duì)CLOB和BLOB數(shù)據(jù)類(lèi)型的操作的相關(guān)資料,這里實(shí)現(xiàn)寫(xiě)入操作與讀寫(xiě)操作,需要的朋友可以參考下2017-08-08
Maven倉(cāng)庫(kù)的具體使用(本地倉(cāng)庫(kù)+遠(yuǎn)程倉(cāng)庫(kù))
Maven 在某個(gè)統(tǒng)一的位置存儲(chǔ)所有項(xiàng)目的構(gòu)件,這個(gè)統(tǒng)一的位置,我們就稱(chēng)之為倉(cāng)庫(kù),本文主要介紹了Maven倉(cāng)庫(kù)的具體使用(本地倉(cāng)庫(kù)+遠(yuǎn)程倉(cāng)庫(kù)),感興趣的可以了解一下2023-11-11
java存儲(chǔ)以及java對(duì)象創(chuàng)建的流程(詳解)
下面小編就為大家?guī)?lái)一篇java存儲(chǔ)以及java對(duì)象創(chuàng)建的流程(詳解)。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2017-05-05
深入理解MyBatis中的一級(jí)緩存與二級(jí)緩存
這篇文章主要給大家深入的介紹了關(guān)于MyBatis中一級(jí)緩存與二級(jí)緩存的相關(guān)資料,文中詳細(xì)介紹MyBatis中一級(jí)緩存與二級(jí)緩存的工作原理及使用,對(duì)大家具有一定的參考性學(xué)習(xí)價(jià)值,需要的朋友們下面來(lái)一起看看吧。2017-06-06
SpringBoot統(tǒng)計(jì)接口調(diào)用耗時(shí)的三種方式
在實(shí)際開(kāi)發(fā)中,了解項(xiàng)目中接口的響應(yīng)時(shí)間是必不可少的事情,SpringBoot 項(xiàng)目支持監(jiān)聽(tīng)接口的功能也不止一個(gè),接下來(lái)我們分別以 AOP、ApplicationListener、Tomcat 三個(gè)方面去實(shí)現(xiàn)三種不同的監(jiān)聽(tīng)接口響應(yīng)時(shí)間的操作,需要的朋友可以參考下2024-06-06
面向?qū)ο缶幊?Java中的抽象數(shù)據(jù)類(lèi)型
面向?qū)ο缶幊?Java中的抽象數(shù)據(jù)類(lèi)型...2006-12-12
Java并發(fā)編程之ReentrantLock實(shí)現(xiàn)原理及源碼剖析
ReentrantLock 是常用的鎖,相對(duì)于Synchronized ,lock鎖更人性化,閱讀性更強(qiáng),文中將會(huì)詳細(xì)的說(shuō)明,請(qǐng)君往下閱讀2021-09-09
Mybatis的xml中使用if/else標(biāo)簽的具體使用
本文主要介紹了Mybatis的xml中使用if/else標(biāo)簽的具體使用,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2022-05-05

