多線程編程大家都覺得比較新鮮而又比較陌生,對于多線程編程的使用場景也不太了解,這個(gè)java并發(fā)編程系列的文章會從基礎(chǔ)開始講起,今天主要講下java中的線程基礎(chǔ)知識,讓大家能快速上手并了解。
0. 線程狀態(tài)
1、新建狀態(tài)(New):新創(chuàng)建了一個(gè)線程對象。
2、就緒狀態(tài)(Runnable):線程對象創(chuàng)建后,其他線程調(diào)用了該對象的start()方法。該狀態(tài)的線程位于可運(yùn)行線程池中,變得可運(yùn)行,等待獲取CPU的使用權(quán)。
3、運(yùn)行狀態(tài)(Running):就緒狀態(tài)的線程獲取了CPU,執(zhí)行程序代碼。
4、阻塞狀態(tài)(Blocked):阻塞狀態(tài)是線程因?yàn)槟撤N原因放棄CPU使用權(quán),暫時(shí)停止運(yùn)行。直到線程進(jìn)入就緒狀態(tài),才有機(jī)會轉(zhuǎn)到運(yùn)行狀態(tài)。阻塞的情況分三種:
(一)、等待阻塞:運(yùn)行的線程執(zhí)行wait()方法,JVM會把該線程放入等待池中。
(二)、同步阻塞:運(yùn)行的線程在獲取對象的同步鎖時(shí),若該同步鎖被別的線程占用,則JVM會把該線程放入鎖池中。
(三)、其他阻塞:運(yùn)行的線程執(zhí)行sleep()或join()方法,或者發(fā)出了I/O請求時(shí),JVM會把該線程置為阻塞狀態(tài)。當(dāng)sleep()狀態(tài)超時(shí)、join()等待線程終止或者超時(shí)、或者I/O處理完畢時(shí),線程重新轉(zhuǎn)入就緒狀態(tài)。
5、死亡狀態(tài)(Dead):線程執(zhí)行完了或者因異常退出了run()方法,該線程結(jié)束生命周期。

1. 線程創(chuàng)建
在java中創(chuàng)建線程非常簡單,有兩種方法,一種是寫一個(gè)線程類直接繼承自concurrent包里的Thread類,重寫run()方法,然后創(chuàng)建該thread實(shí)例后直接調(diào)用start方法線程就可以執(zhí)行線程中的run()方法了;
public static class MyThread2 extends Thread {
@Override
public void run(){
System.out.println("MyThread2 run!");
}
}
還有種方法是實(shí)現(xiàn)Runable接口,實(shí)現(xiàn)接口中的Run方法,然后初始化線程的時(shí)候?qū)⒃摼€程實(shí)現(xiàn)類作為Thread構(gòu)造函數(shù)的入?yún)?,進(jìn)行創(chuàng)建線程,建議使用第二種方式,因?yàn)槭褂美^承Thread的方式會導(dǎo)致自定義線程的擴(kuò)展性變差,java種繼承只能繼承一個(gè)類,但是可以實(shí)現(xiàn)多個(gè)接口。
public class MyThread implements Runnable {
@Override
public void run() {
System.out.println("MyThread run!");
}
}
public static void main(String[] args) {
Thread thread1 = new Thread(new MyThread());
thread1.start();
System.out.println("main finished!");
}
2. 線程停止
停止線程比較簡單,直接調(diào)用線程的stop方法,但是對于stop方法最好少用因?yàn)檎{(diào)用stop后,會立即終止線程,有可能導(dǎo)致多線程間共享的數(shù)據(jù)產(chǎn)生不一致的情況,所以如果要終止線程最好是自定義一個(gè)變量,通過該boolean變量來保證線程退出自然終止。
3. 線程間數(shù)據(jù)共享
在線程間共享數(shù)據(jù)是常常會遇到的問題,一般共享數(shù)據(jù)大家都是定義一個(gè)static變量多線程來共享,但是這就帶來一個(gè)問題,static變量在內(nèi)存中是沒有鎖保護(hù)的,很容易出現(xiàn)數(shù)據(jù)因?yàn)椴⑿芯€程導(dǎo)致覆蓋的問題,所以后面的系列文章,我會詳細(xì)講解下有哪些方法可以保證數(shù)據(jù)的一致性。
4. 線程等待、恢復(fù)
從上面的線程狀態(tài)圖中可以看到,在運(yùn)行過程中的線程通過wait方法會進(jìn)入等待狀態(tài),當(dāng)線程中調(diào)用notify或者notifyAll方法則會隨機(jī)喚醒等待隊(duì)列中的一個(gè)線程或者喚醒所有線程繼續(xù)執(zhí)行。