av激情亚洲男人的天堂国语,日韩欧美精品一中文字幕,无码av一区二区三区无码,国产又色又爽又刺激的a片,国产又色又爽又刺激的a片

「高并發(fā)」線程到底是按照怎樣的順序執(zhí)行的?

一、線程的執(zhí)行順序是不確定的

調(diào)用Thread的start()方法啟動(dòng)線程時(shí),線程的執(zhí)行順序是不確定的。也就是說(shuō),在同一個(gè)方法中,連續(xù)創(chuàng)建多個(gè)線程后,調(diào)用線程的start()方法的順序并不能決定線程的執(zhí)行順序。

目前創(chuàng)新互聯(lián)已為超過(guò)千家的企業(yè)提供了網(wǎng)站建設(shè)、域名、網(wǎng)頁(yè)空間、綿陽(yáng)服務(wù)器托管、企業(yè)網(wǎng)站設(shè)計(jì)、興安盟網(wǎng)站維護(hù)等服務(wù),公司將堅(jiān)持客戶導(dǎo)向、應(yīng)用為本的策略,正道將秉承"和諧、參與、激情"的文化,與客戶和合作伙伴齊心協(xié)力一起成長(zhǎng),共同發(fā)展。

例如,在這里,看一個(gè)簡(jiǎn)單的示例程序,如下所示。

package io.binghe.concurrent.lab03;

/**
* @author binghe
* @version 1.0.0
* @description 線程的順序,直接調(diào)用Thread.start()方法執(zhí)行不能確保線程的執(zhí)行順序
*/
public class ThreadSort01 {
public static void main(String[] args){
Thread thread1 = new Thread(() -> {
System.out.println("thread1");
});
Thread thread2 = new Thread(() -> {
System.out.println("thread2");
});
Thread thread3 = new Thread(() -> {
System.out.println("thread3");
});

thread1.start();
thread2.start();
thread3.start();
}
}

在ThreadSort01類(lèi)中分別創(chuàng)建了三個(gè)不同的線程,thread1、thread2和thread3,接下來(lái),在程序中按照順序分別調(diào)用thread1.start()、thread2.start()和thread3.start()方法來(lái)分別啟動(dòng)三個(gè)不同的線程。

那么,問(wèn)題來(lái)了,線程的執(zhí)行順序是否按照thread1、thread2和thread3的順序執(zhí)行呢?運(yùn)行ThreadSort01的main方法,結(jié)果如下所示。

thread1
thread2
thread3

再次運(yùn)行時(shí),結(jié)果如下所示。

thread1
thread3
thread2

第三次運(yùn)行時(shí),結(jié)果如下所示。

thread2
thread3
thread1

可以看到,每次運(yùn)行程序時(shí),線程的執(zhí)行順序可能不同。線程的啟動(dòng)順序并不能決定線程的執(zhí)行順序。

二、如何確保線程的執(zhí)行順序

1.確保線程執(zhí)行順序的簡(jiǎn)單示例

在實(shí)際業(yè)務(wù)場(chǎng)景中,有時(shí),后啟動(dòng)的線程可能需要依賴先啟動(dòng)的線程執(zhí)行完成才能正確地執(zhí)行線程中的業(yè)務(wù)邏輯。此時(shí),就需要確保線程的執(zhí)行順序。那么如何確保線程的執(zhí)行順序呢?

可以使用Thread類(lèi)中的join()方法來(lái)確保線程的執(zhí)行順序。例如,下面的測(cè)試代碼。

package io.binghe.concurrent.lab03;

/**
* @author binghe
* @version 1.0.0
* @description 線程的順序,Thread.join()方法能夠確保線程的執(zhí)行順序
*/
public class ThreadSort02 {
public static void main(String[] args) throws InterruptedException {

Thread thread1 = new Thread(() -> {
System.out.println("thread1");
});
Thread thread2 = new Thread(() -> {
System.out.println("thread2");
});
Thread thread3 = new Thread(() -> {
System.out.println("thread3");
});

thread1.start();

//實(shí)際上讓主線程等待子線程執(zhí)行完成
thread1.join();

thread2.start();
thread2.join();

thread3.start();
thread3.join();
}
}

可以看到,ThreadSot02類(lèi)比ThreadSort01類(lèi),在每個(gè)線程的啟動(dòng)方法下面添加了調(diào)用線程的join()方法。此時(shí),運(yùn)行ThreadSort02類(lèi),結(jié)果如下所示。

thread1
thread2
thread3

再次運(yùn)行時(shí),結(jié)果如下所示。

thread1
thread2
thread3

第三次運(yùn)行時(shí),結(jié)果如下所示。

thread1
thread2
thread3

可以看到,每次運(yùn)行的結(jié)果都是相同的,所以,使用Thread的join()方法能夠保證線程的先后執(zhí)行順序。

2.join方法如何確保線程的執(zhí)行順序

既然Thread類(lèi)的join()方法能夠確保線程的執(zhí)行順序,我們就一起來(lái)看看Thread類(lèi)的join()方法到底是個(gè)什么鬼。

進(jìn)入Thread的join()方法,如下所示。

public final void join() throws InterruptedException {
join(0);
}

可以看到j(luò)oin()方法調(diào)用同類(lèi)中的一個(gè)有參join()方法,并傳遞參數(shù)0。繼續(xù)跟進(jìn)代碼,如下所示。

public final synchronized void join(long millis)
throws InterruptedException {
long base = System.currentTimeMillis();
long now = 0;

if (millis < 0) {
throw new IllegalArgumentException("timeout value is negative");
}

if (millis == 0) {
while (isAlive()) {
wait(0);
}
} else {
while (isAlive()) {
long delay = millis - now;
if (delay <= 0) {
break;
}
wait(delay);
now = System.currentTimeMillis() - base;
}
}
}

可以看到,有一個(gè)long類(lèi)型參數(shù)的join()方法使用了synchroinzed修飾,說(shuō)明這個(gè)方法同一時(shí)刻只能被一個(gè)實(shí)例或者方法調(diào)用。由于,傳遞的參數(shù)為0,所以,程序會(huì)進(jìn)入如下代碼邏輯。

if (millis == 0) {
while (isAlive()) {
wait(0);
}
}

首先,在代碼中以while循環(huán)的方式來(lái)判斷當(dāng)前線程是否已經(jīng)啟動(dòng)處于活躍狀態(tài),如果已經(jīng)啟動(dòng)處于活躍狀態(tài),則調(diào)用同類(lèi)中的wait()方法,并傳遞參數(shù)0。繼續(xù)跟進(jìn)wait()方法,如下所示。

public final native void wait(long timeout) throws InterruptedException;

可以看到,wait()方法是一個(gè)本地方法,通過(guò)JNI的方式調(diào)用JDK底層的方法來(lái)使線程等待執(zhí)行完成。

需要注意的是,調(diào)用線程的wait()方法時(shí),會(huì)使主線程處于等待狀態(tài),等待子線程執(zhí)行完成后再次向下執(zhí)行。也就是說(shuō),在ThreadSort02類(lèi)的main()方法中,調(diào)用子線程的join()方法,會(huì)阻塞main()方法的執(zhí)行,當(dāng)子線程執(zhí)行完成后,main()方法會(huì)繼續(xù)向下執(zhí)行,啟動(dòng)第二個(gè)子線程,并執(zhí)行子線程的業(yè)務(wù)邏輯,以此類(lèi)推。


本文名稱(chēng):「高并發(fā)」線程到底是按照怎樣的順序執(zhí)行的?
地址分享:http://uogjgqi.cn/article/cdeopje.html
掃二維碼與項(xiàng)目經(jīng)理溝通

我們?cè)谖⑿派?4小時(shí)期待你的聲音

解答本文疑問(wèn)/技術(shù)咨詢/運(yùn)營(yíng)咨詢/技術(shù)建議/互聯(lián)網(wǎng)交流