您好,登錄后才能下訂單哦!
繼承Thread類方式
1. 線程啟動(dòng)時(shí):一定是調(diào)用Thread類的start()方法,因?yàn)橥ㄟ^(guò)源碼解析發(fā)現(xiàn),start()方法中,最后會(huì)調(diào)用以native關(guān)鍵字修飾的start0()方法,該方法會(huì)通過(guò)JVM實(shí)現(xiàn)不同操作系統(tǒng)不同實(shí)現(xiàn)的
資源調(diào)度分配;
2. Native關(guān)鍵字:調(diào)用本機(jī)的操作系統(tǒng)函數(shù)。
實(shí)現(xiàn)Runnable接口方式
1. 實(shí)現(xiàn)Runnable接口:由于繼承Thread類會(huì)造成單繼承的局限性,所以利用接口來(lái)實(shí)現(xiàn);
2. Runnable接口:因?yàn)槠涫呛瘮?shù)式接口,所以該接口中只有一個(gè)方法,可以使用Lamda表達(dá)式完成;
3. @FunctionalInterface:修飾的接口為函數(shù)式接口;
4. 由于啟動(dòng)發(fā)多線程只能通過(guò)start()方法,但Runnable方法中沒(méi)有此方法,故實(shí)現(xiàn)該接口并啟動(dòng)一個(gè)線程,是通過(guò)Thread的構(gòu)造函數(shù)發(fā)現(xiàn):
public Thread(Runnable targer) ,所以可以通過(guò)此方式來(lái)啟動(dòng)一個(gè)多線程;
實(shí)例:Runnnable接口方式
public class Test11 { public static void main(String[] args) { Test11Demo t1 = new Test11Demo("線程1"); Test11Demo t2 = new Test11Demo("線程2"); Test11Demo t3 = new Test11Demo("線程3"); new Thread(t1).start(); new Thread(t2).start(); new Thread(t3).start(); } } class Test11Demo implements Runnable { private String name; Test11Demo(String name) { this.name = name; } @Override public void run() { for (int x = 0; x < 10; x++) { System.out.println(this.name + ",x=" + x); } } }
實(shí)例:Lamda方式,內(nèi)部類方式
在原來(lái)代碼基礎(chǔ)上,添加測(cè)試代碼
public static void main(String[] args) throws Exception { Test11Demo t1 = new Test11Demo("線程1"); Test11Demo t2 = new Test11Demo("線程2"); Test11Demo t3 = new Test11Demo("線程3"); new Thread(t1).start(); new Thread(t2).start(); new Thread(t3).start(); final String name1 = "Lamda測(cè)試"; new Thread( ()->{ for (int x = 0; x < 10; x++) { System.out.println(name1 + ",x=" + x); } }).start(); final String name = "內(nèi)部類測(cè)試"; new Thread(new Runnable() { @Override public void run() { for (int x = 0; x < 10; x++) { System.out.println(name + ",x=" + x); } } }).start(); }
兩種方式,啟動(dòng)線程的異同
1. 查看源碼可知,Thread類定義:
public classThread extends Object implements Runnable
2. 類關(guān)系圖:
綜上,可知,
多線程需要一個(gè)線程主類:可以繼承Thread類,也可以實(shí)現(xiàn)Runnable接口;
使用Runnable接口,可以更好的實(shí)現(xiàn)數(shù)據(jù)共享的操作;并可以避免Thread類帶來(lái)的單繼承局限性;
線程的命名和取得
1. 線程的所有操作方法基本上都已經(jīng)在Thread類中定義完整;
2. 如下方法,可提供線程名稱操作:
① 構(gòu)造方法:public Thread(Runnable target,String name)
② 設(shè)置名字:public final void setName(String name)
③ 獲取名字:public final String getName()
④ 由于線程執(zhí)行本身不確定狀態(tài),
提供方法:public static Thread currentThread()來(lái)取得當(dāng)前線程
3. 如果在設(shè)置線程對(duì)象名稱時(shí),沒(méi)有設(shè)置具體名字,則會(huì)采用默認(rèn)名字進(jìn)行定義;
4. 每一個(gè)JVM至少會(huì)啟動(dòng)兩個(gè)線程:主線程,GC線程;
線程的休眠
休眠方法:sleep();線程的睡眠,是有先后順序的
線程的優(yōu)先級(jí)
1. 優(yōu)先級(jí)操作方法:
設(shè)置優(yōu)先級(jí):public final void setPriority(int newPriority);
取得優(yōu)先級(jí):public final int getPriority();
2. 優(yōu)先級(jí)相關(guān)常量:
最高優(yōu)先級(jí):public final static int MAX_PRIORITY = 10;
中等優(yōu)先級(jí):public final static int NORM_PRIORITY = 5;
最低優(yōu)先級(jí):public final static int MIN_PRIORITY = 1;
3. 理論上,會(huì)根據(jù)設(shè)置的優(yōu)先級(jí)進(jìn)行線程的啟動(dòng)運(yùn)行;
主線程,屬于一般優(yōu)先級(jí)。
1. 同步問(wèn)題的引出:多個(gè)線程需要訪問(wèn)統(tǒng)一資源;
2. 同步代碼塊執(zhí)行效率要低于異步,同步代碼塊使用:synchronized關(guān)鍵字
3. 異步執(zhí)行效率高,但數(shù)據(jù)不準(zhǔn)確;同步代碼執(zhí)行效率慢,但會(huì)保證數(shù)據(jù)的有效性,同時(shí)線程安全。
4. 死鎖:(了解) 如果程序中出現(xiàn)過(guò)多同步,將會(huì)產(chǎn)生死鎖問(wèn)題;
---下一篇,線程中的生產(chǎn)者與消費(fèi)者理解--線程的應(yīng)用場(chǎng)景之一
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。