這篇文章給大家分享的是有關(guān)java線程基礎(chǔ)知識點有哪些的內(nèi)容。小編覺得挺實用的,因此分享給大家做個參考,一起跟隨小編過來看看吧。
我們擁有10余年網(wǎng)頁設(shè)計和網(wǎng)站建設(shè)經(jīng)驗,從網(wǎng)站策劃到網(wǎng)站制作,我們的網(wǎng)頁設(shè)計師為您提供的解決方案。為企業(yè)提供成都網(wǎng)站制作、成都網(wǎng)站建設(shè)、微信開發(fā)、微信小程序開發(fā)、手機(jī)網(wǎng)站開發(fā)、HTML5、等業(yè)務(wù)。無論您有什么樣的網(wǎng)站設(shè)計或者設(shè)計方案要求,我們都將富于創(chuàng)造性的提供專業(yè)設(shè)計服務(wù)并滿足您的需求。
java中建立線程可以有兩種方式,分別是繼承Thread類和實現(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("線程1").start(); new MyThread("線程2").start(); } } /* 線程1--0 線程1--1 線程1--2 線程1--3 線程1--4 線程2--0 線程2--1 線程2--2 線程2--3 線程2--4 */
如上,java中的線程對象必須一個類的形式創(chuàng)建,而該類中必須重寫基類的run()方法,該方法其實就是線程的執(zhí)行體。調(diào)用該類實例的start方法則就隱式的調(diào)用了run方法。
不難看出,由于new了2次MyThread,所以兩次的實例是不同的,即各自都有各自的i變量,相互獨立。
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,"線程1").start(); new Thread(myRun,"線程2").start(); } } /* 線程1--0 線程1--1 線程2--0 線程2--3 線程2--4 線程2--5 線程2--6 線程2--7 線程2--8 線程2--9 線程2--10 線程2--11 線程2--12 線程2--13 線程2--14 線程2--15 線程1--2 線程2--16 線程2--18 線程2--19 線程2--20 線程2--21 線程2--22 線程2--23 線程2--24 線程1--17 線程2--25 線程1--26 線程2--27 線程1--28 線程1--30 線程2--29 線程1--31 線程2--32 線程2--34 線程2--35 線程2--36 線程2--37 線程1--33 線程2--38 線程1--39 線程1--41 線程2--40 線程1--42 線程1--44 線程1--45 線程2--43 線程1--46 線程2--47 線程2--49 線程1--48 */
可以看出,由于實現(xiàn)這種方式是將某一個對象做為target加載到Thread類上,所以即使new再多的Thread對象,只要target是同一引用的對象,則就調(diào)用該對象的run方法,所有線程均共享該target對象的資源,所以會看到線程1和線程2一共輸出了51次,2條線程共同完成了i從0到49的輸出,而并不像上面那樣分別輸出5次。至于為什么輸出了51條,兩條線程幾乎在同一時刻進(jìn)入就緒狀態(tài)(start方法只是讓線程進(jìn)入就緒狀態(tài)),觀察上面的i變量不難發(fā)現(xiàn)當(dāng)i等于0時,此時線程1和線程2均同時處于運行狀態(tài),產(chǎn)生了并發(fā)現(xiàn)象,共同輸出了i=0,而此之后CPU通過不斷的切換線程,使得在同一時刻只有一條線程在輸出。
線程狀態(tài)
線程分為4個狀態(tài)
就緒狀態(tài):調(diào)用start方法則進(jìn)入就緒狀態(tài)。
運行狀態(tài):處于就緒狀態(tài)的線程會被jvm進(jìn)行調(diào)度從而成為運行狀態(tài)。
阻塞狀態(tài):如有某些同步方法未返回結(jié)果則出現(xiàn)阻塞狀態(tài),或sleep和yeild。
死亡狀態(tài):方法體執(zhí)行完畢或者強(qiáng)行stop某個線程。
線程的基本操作
join()合并線程:當(dāng)前線程調(diào)用某線程的join方法后將會等待某線程執(zhí)行完畢后本線程才會繼續(xù)。
sleep(long milliseconds)線程睡眠:阻塞當(dāng)前線程,只有阻塞的時間到了才會繼續(xù)下去。再阻塞的同時,會將CPU占有權(quán)交給其他線程,所以常常利用sleep(1)來切換線程。
**yield()線程讓步:**yeild類似與sleep,但是它只會讓步于比自己級別高或者同級別的其他線程,若沒有其他線程均比自己級別低則再次執(zhí)行本線程。
后臺線程
一個程序被操作系統(tǒng)執(zhí)行后將有一個進(jìn)程,一個進(jìn)程至少有一個線程(主線程),主線程并沒有比其他線程有太多的特殊之處,只因為它是最早被執(zhí)行的線程,在主線程中將會創(chuàng)建其他線程,若不指明則默認(rèn)創(chuàng)建的是前臺線程(包括main線程),若調(diào)用setDaemon(true)則顯式的將該線程設(shè)置為后臺線程,后臺線程為Daemon線程,從名字就能看出,它的主要作用是為其他線程提供守護(hù),服務(wù)的功能。當(dāng)所有前臺線程結(jié)束后,后臺線程將會被強(qiáng)制結(jié)束,因為它此時已經(jīng)沒有存在的意義了。
前臺線程
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("線程A"); //th.setDaemon(true); th.start(); int j; for(j=0;j<3;j++){ System.out.println(Thread.currentThread().getName()+"--"+j); } } }
程序完整的輸出子線程中0到9998;說明主線程并沒有什么特殊的,它的結(jié)束并不會影響其他前臺線程的運行。
后臺線程
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("線程A"); th.setDaemon(true); th.start(); int j; for(j=0;j<3;j++){ System.out.println(Thread.currentThread().getName()+"--"+j); } } }
程序并不能完整的輸出0-9998就退出了,說明前臺主線程結(jié)束后,jvm強(qiáng)制結(jié)束了后臺線程。
感謝各位的閱讀!關(guān)于“java線程基礎(chǔ)知識點有哪些”這篇文章就分享到這里了,希望以上內(nèi)容可以對大家有一定的幫助,讓大家可以學(xué)到更多知識,如果覺得文章不錯,可以把它分享出去讓更多的人看到吧!