線程是什么?
線程(Thread)是一個(gè)對(duì)象(Object)。用來(lái)干什么?Java 線程(也稱 JVM 線程)是 Java 進(jìn)程內(nèi)允許多個(gè)同時(shí)進(jìn)行的任務(wù)。該進(jìn)程內(nèi)并發(fā)的任務(wù)成為線程(Thread),一個(gè)進(jìn)程里至少一個(gè)線程。
創(chuàng)新互聯(lián)是一家集網(wǎng)站建設(shè),遂溪企業(yè)網(wǎng)站建設(shè),遂溪品牌網(wǎng)站建設(shè),網(wǎng)站定制,遂溪網(wǎng)站建設(shè)報(bào)價(jià),網(wǎng)絡(luò)營(yíng)銷,網(wǎng)絡(luò)優(yōu)化,遂溪網(wǎng)站推廣為一體的創(chuàng)新建站企業(yè),幫助傳統(tǒng)企業(yè)提升企業(yè)形象加強(qiáng)企業(yè)競(jìng)爭(zhēng)力。可充分滿足這一群體相比中小企業(yè)更為豐富、高端、多元的互聯(lián)網(wǎng)需求。同時(shí)我們時(shí)刻保持專業(yè)、時(shí)尚、前沿,時(shí)刻以成就客戶成長(zhǎng)自我,堅(jiān)持不斷學(xué)習(xí)、思考、沉淀、凈化自己,讓我們?yōu)楦嗟钠髽I(yè)打造出實(shí)用型網(wǎng)站。
Java 程序采用多線程方式來(lái)支持大量的并發(fā)請(qǐng)求處理,程序如果在多線程方式執(zhí)行下,其復(fù)雜度遠(yuǎn)高于單線程串行執(zhí)行。那么多線程:指的是這個(gè)程序(一個(gè)進(jìn)程)運(yùn)行時(shí)產(chǎn)生了不止一個(gè)線程。
為啥使用多線程?
聊到多線程,多半會(huì)聊并發(fā)與并行,咋理解并區(qū)分這兩個(gè)的區(qū)別呢?
Java 創(chuàng)建線程對(duì)象有兩種方法:
– 繼承 Thread 類創(chuàng)建線程對(duì)象
– 實(shí)現(xiàn) Runnable 接口類創(chuàng)建線程對(duì)象
新建 MyThread 對(duì)象,代碼如下:
/**
* 繼承 Thread 類創(chuàng)建線程對(duì)象
* @author Jeff Lee @ bysocket.com
* @since 2018年01月27日21:03:02
*/
public class MyThread extends Thread {
@Override // 可以省略
public void run() {
System.out.println("MyThread 的線程對(duì)象正在執(zhí)行任務(wù)");
}
public static void main(String[] args) {
for (int i = 0; i < 10; i++) {
MyThread thread = new MyThread();
thread.start();
System.out.println("MyThread 的線程對(duì)象 " + thread.getId());
}
}
}
MyThread 類繼承了 Thread 對(duì)象,并重寫(Override)了 run 方法,實(shí)現(xiàn)線程里面的邏輯。main 函數(shù)是使用 for 語(yǔ)句,循環(huán)創(chuàng)建了 10 個(gè)線程,調(diào)用 start 方法啟動(dòng)線程,最后打印當(dāng)前線程對(duì)象的 ID。
run 方法和 start 方法的區(qū)別是什么呢?
run 方法就是跑的意思,線程啟動(dòng)后,會(huì)調(diào)用 run 方法。
start 方法就是啟動(dòng)的意思,就是啟動(dòng)新線程實(shí)例。啟動(dòng)線程后,才會(huì)調(diào)線程的 run 方法。
執(zhí)行 main 方法后,控制臺(tái)打印如下:
MyThread 的線程對(duì)象正在執(zhí)行任務(wù)
MyThread 的線程對(duì)象 10
MyThread 的線程對(duì)象正在執(zhí)行任務(wù)
MyThread 的線程對(duì)象 11
MyThread 的線程對(duì)象正在執(zhí)行任務(wù)
MyThread 的線程對(duì)象 12
MyThread 的線程對(duì)象正在執(zhí)行任務(wù)
MyThread 的線程對(duì)象 13
MyThread 的線程對(duì)象正在執(zhí)行任務(wù)
MyThread 的線程對(duì)象 14
MyThread 的線程對(duì)象正在執(zhí)行任務(wù)
MyThread 的線程對(duì)象 15
MyThread 的線程對(duì)象正在執(zhí)行任務(wù)
MyThread 的線程對(duì)象 16
MyThread 的線程對(duì)象正在執(zhí)行任務(wù)
MyThread 的線程對(duì)象 17
MyThread 的線程對(duì)象正在執(zhí)行任務(wù)
MyThread 的線程對(duì)象 18
MyThread 的線程對(duì)象正在執(zhí)行任務(wù)
MyThread 的線程對(duì)象 19
可見,線程的 ID 是線程唯一標(biāo)識(shí)符,每個(gè)線程 ID 都是不一樣的。
start 方法和 run 方法的關(guān)系如圖所示:
同理,實(shí)現(xiàn) Runnable 接口類創(chuàng)建線程對(duì)象也很簡(jiǎn)單,只是不同的形式。新建 MyThreadBrother 代碼如下:
/**
* 實(shí)現(xiàn) Runnable 接口類創(chuàng)建線程對(duì)象
* @author Jeff Lee @ bysocket.com
* @since 2018年01月27日21:22:57
*/
public class MyThreadBrother implements Runnable {
@Override // 可以省略
public void run() {
System.out.println("MyThreadBrother 的線程對(duì)象正在執(zhí)行任務(wù)");
}
public static void main(String[] args) {
for (int i = 0; i < 10; i++) {
Thread thread = new Thread(new MyThreadBrother());
thread.start();
System.out.println("MyThreadBrother 的線程對(duì)象 " + thread.getId());
}
}
}
具體代碼:java-concurrency-core-learning
在運(yùn)行上面兩個(gè)小 demo 后,JVM 執(zhí)行了 main 函數(shù)線程,然后在主線程中執(zhí)行創(chuàng)建了新的線程。正常情況下,所有線程執(zhí)行到運(yùn)行結(jié)束為止。除非某個(gè)線程中調(diào)用了 System.exit(1) 則被終止。
在實(shí)際開發(fā)中,一個(gè)請(qǐng)求到響應(yīng)式是一個(gè)線程。但在這個(gè)線程中可以使用線程池創(chuàng)建新的線程,去執(zhí)行任務(wù)。
新建 MyThreadInfo 類,打印線程對(duì)象屬性,代碼如下:
/**
* 線程實(shí)例對(duì)象的屬性值
* @author Jeff Lee @ bysocket.com
* @since 2018年01月27日21:24:40
*/
public class MyThreadInfo extends Thread {
@Override // 可以省略
public void run() {
System.out.println("MyThreadInfo 的線程實(shí)例正在執(zhí)行任務(wù)");
// System.exit(1);
}
public static void main(String[] args) {
MyThreadInfo thread = new MyThreadInfo();
thread.start();
System.out.print("MyThreadInfo 的線程對(duì)象 \n"
+ "線程唯一標(biāo)識(shí)符:" + thread.getId() + "\n"
+ "線程名稱:" + thread.getName() + "\n"
+ "線程狀態(tài):" + thread.getState() + "\n"
+ "線程優(yōu)先級(jí):" + thread.getPriority());
}
}
執(zhí)行代碼打印如下:
MyThreadInfo 的線程實(shí)例正在執(zhí)行任務(wù)
MyThreadInfo 的線程對(duì)象
線程唯一標(biāo)識(shí)符:10
線程名稱:Thread-0
線程狀態(tài):NEW
線程優(yōu)先級(jí):5
線程是一個(gè)對(duì)象,它有唯一標(biāo)識(shí)符 ID、名稱、狀態(tài)、優(yōu)先級(jí)等屬性。線程只能修改其優(yōu)先級(jí)和名稱等屬性 ,無(wú)法修改 ID 、狀態(tài)。ID 是 JVM 分配的,名字默認(rèn)也為 Thread-XX,XX是一組數(shù)字。線程初始狀態(tài)為 NEW。
線程優(yōu)先級(jí)的范圍是 1 到 10 ,其中 1 是最低優(yōu)先級(jí),10 是最高優(yōu)先級(jí)。不推薦改變線程的優(yōu)先級(jí),如果業(yè)務(wù)需要,自然可以修改線程優(yōu)先級(jí)到最高,或者最低。
線程的狀態(tài)實(shí)現(xiàn)通過(guò) Thread.State 常量類實(shí)現(xiàn),有 6 種線程狀態(tài):new(新建)、runnnable(可運(yùn)行)、blocked(阻塞)、waiting(等待)、time waiting (定時(shí)等待)和 terminated(終止)。狀態(tài)轉(zhuǎn)換圖如下:
線程狀態(tài)流程大致如下:
本文介紹了線程與多線程的基礎(chǔ)篇,包括了線程啟動(dòng)及線程狀態(tài)等。下一篇我們聊下線程的具體操作。包括中斷、終止等
針對(duì)于上面所涉及到的知識(shí)點(diǎn)我總結(jié)出了有1到5年開發(fā)經(jīng)驗(yàn)的程序員在面試中涉及到的絕大部分架構(gòu)面試題及答案做成了文檔和架構(gòu)視頻資料免費(fèi)分享給大家(包括Dubbo、redis、Netty、zookeeper、Spring cloud、分布式、高并發(fā)等架構(gòu)技術(shù)資料),希望能幫助到您面試前的復(fù)習(xí)且找到一個(gè)好的工作,也節(jié)省大家在網(wǎng)上搜索資料的時(shí)間來(lái)學(xué)習(xí),也可以關(guān)注我一下以后會(huì)有更多干貨分享。