Java并發(fā)編程之線(xiàn)程創(chuàng)建介紹
1.線(xiàn)程與進(jìn)程
進(jìn)程是代碼在數(shù)據(jù)集合上的一次運(yùn)行活動(dòng),是系統(tǒng)進(jìn)行資源分配和調(diào)度的基本單位,線(xiàn)程則是一個(gè)實(shí)體,一個(gè)進(jìn)程中至少有一個(gè)線(xiàn)程,是CPU調(diào)度和分配的基本單位,進(jìn)程中的多個(gè)線(xiàn)程共享進(jìn)程的資源。
進(jìn)程的三個(gè)特征:
- 動(dòng)態(tài)性 : 進(jìn)程是運(yùn)行中的程序,要?jiǎng)討B(tài)的占用內(nèi)存,CPU和網(wǎng)絡(luò)等資源。
- 獨(dú)立性 : 進(jìn)程與進(jìn)程之間是相互獨(dú)立的,彼此有自己的獨(dú)立內(nèi)存區(qū)域。
- 并發(fā)性 : 假如CPU是單核,同一個(gè)時(shí)刻其實(shí)內(nèi)存中只有一個(gè)進(jìn)程在被執(zhí)行。CPU會(huì)分時(shí)輪詢(xún)切換依次為每個(gè)進(jìn)程服務(wù),因?yàn)榍袚Q的速度非???,給我們的感覺(jué)這些進(jìn)程在同時(shí)執(zhí)行,這就是并發(fā)性。
2.線(xiàn)程的創(chuàng)建與運(yùn)行
我們?cè)谶M(jìn)程中創(chuàng)建線(xiàn)程的方式有三種:
- 方式一:繼承Thread類(lèi)的方式
- 1.定義一個(gè)線(xiàn)程類(lèi)繼承Thread類(lèi)。
- 2.重寫(xiě)run()方法
- 3.創(chuàng)建一個(gè)新的線(xiàn)程對(duì)象。
- 4.調(diào)用線(xiàn)程對(duì)象的start()方法啟動(dòng)線(xiàn)程。
public class ThreadDemo {
// 啟動(dòng)后的ThreadDemo當(dāng)成一個(gè)進(jìn)程。
// main方法是由主線(xiàn)程執(zhí)行的,理解成main方法就是一個(gè)主線(xiàn)程
public static void main(String[] args) {
// 3.創(chuàng)建一個(gè)線(xiàn)程對(duì)象
Thread t = new MyThread();
// 4.調(diào)用線(xiàn)程對(duì)象的start()方法啟動(dòng)線(xiàn)程,最終還是執(zhí)行run()方法!
t.start();
for(int i = 0 ; i < 100 ; i++ ){
System.out.println("main線(xiàn)程輸出:"+i);
}
}
}
// 1.定義一個(gè)線(xiàn)程類(lèi)繼承Thread類(lèi)。
class MyThread extends Thread{
// 2.重寫(xiě)run()方法
@Override
public void run() {
// 線(xiàn)程的執(zhí)行方法。
for(int i = 0 ; i < 100 ; i++ ){
System.out.println("子線(xiàn)程輸出:"+i);
}
}
}
優(yōu)點(diǎn):編碼簡(jiǎn)單,在run()方法內(nèi)獲取當(dāng)前線(xiàn)程直接使用this就可以了,無(wú)需使用Thread.currentThread()方法。 缺點(diǎn):線(xiàn)程類(lèi)已經(jīng)繼承了Thread類(lèi)無(wú)法繼承其他類(lèi)了,功能不能通過(guò)繼承拓(單繼承的局限性)。另外任務(wù)與代碼沒(méi)有分離,當(dāng)多個(gè)線(xiàn)程執(zhí)行一樣的任務(wù)時(shí)需要多份任務(wù)代碼。
小結(jié):
- 線(xiàn)程類(lèi)是繼承了Thread的類(lèi)。
- 啟動(dòng)線(xiàn)程必須調(diào)用start()方法。
- 多線(xiàn)程是并發(fā)搶占CPU執(zhí)行,所以在執(zhí)行的過(guò)程中會(huì)出現(xiàn)并發(fā)隨機(jī)性
方式二:實(shí)現(xiàn)Runnable接口的方式。
- 1.創(chuàng)建一個(gè)線(xiàn)程任務(wù)類(lèi)實(shí)現(xiàn)Runnable接口。
- 2.重寫(xiě)run()方法
- 3.創(chuàng)建一個(gè)線(xiàn)程任務(wù)對(duì)象。
- 4.把線(xiàn)程任務(wù)對(duì)象包裝成線(xiàn)程對(duì)象
- 5.調(diào)用線(xiàn)程對(duì)象的start()方法啟動(dòng)線(xiàn)程。
public class ThreadDemo {
public static void main(String[] args) {
// 3.創(chuàng)建一個(gè)線(xiàn)程任務(wù)對(duì)象(注意:線(xiàn)程任務(wù)對(duì)象不是線(xiàn)程對(duì)象,只是執(zhí)行線(xiàn)程的任務(wù)的)
Runnable target = new MyRunnable();
// 4.把線(xiàn)程任務(wù)對(duì)象包裝成線(xiàn)程對(duì)象.且可以指定線(xiàn)程名稱(chēng)
// Thread t = new Thread(target);
Thread t = new Thread(target,"1號(hào)線(xiàn)程");
// 5.調(diào)用線(xiàn)程對(duì)象的start()方法啟動(dòng)線(xiàn)程
t.start();
Thread t2 = new Thread(target);
// 調(diào)用線(xiàn)程對(duì)象的start()方法啟動(dòng)線(xiàn)程
t2.start();
for(int i = 0 ; i < 10 ; i++ ){
System.out.println(Thread.currentThread().getName()+"==>"+i);
}
}
}
// 1.創(chuàng)建一個(gè)線(xiàn)程任務(wù)類(lèi)實(shí)現(xiàn)Runnable接口。
class MyRunnable implements Runnable{
// 2.重寫(xiě)run()方法
@Override
public void run() {
for(int i = 0 ; i < 10 ; i++ ){
System.out.println(Thread.currentThread().getName()+"==>"+i);
}
}
}
優(yōu)點(diǎn):
線(xiàn)程任務(wù)類(lèi)只是實(shí)現(xiàn)了Runnable接口,可以繼續(xù)繼承其他類(lèi),而且可以繼續(xù)實(shí)現(xiàn)其他接口(避免了單繼承的局限性)。 同一個(gè)線(xiàn)程任務(wù)對(duì)象可以被包裝成多個(gè)線(xiàn)程對(duì)象,適合多個(gè)多個(gè)線(xiàn)程去共享同一個(gè)資源。實(shí)現(xiàn)解耦操作,線(xiàn)程任務(wù)代碼可以被多個(gè)線(xiàn)程共享,線(xiàn)程任務(wù)代碼和線(xiàn)程獨(dú)立。
方法三:實(shí)現(xiàn)Callable接口
- 1.定義一個(gè)線(xiàn)程任務(wù)類(lèi)實(shí)現(xiàn)Callable接口 , 申明線(xiàn)程執(zhí)行的結(jié)果類(lèi)型。
- 2.重寫(xiě)線(xiàn)程任務(wù)類(lèi)的call方法,這個(gè)方法可以直接返回執(zhí)行的結(jié)果。
- 3.創(chuàng)建一個(gè)Callable的線(xiàn)程任務(wù)對(duì)象。
- 4.把Callable的線(xiàn)程任務(wù)對(duì)象包裝成一個(gè)FutureTask對(duì)象。
- 5.把FutureTask對(duì)象包裝成線(xiàn)程對(duì)象。
- 6.調(diào)用線(xiàn)程的start()方法啟動(dòng)線(xiàn)程 。
public class ThreadDemo {
public static void main(String[] args) {
// 3.創(chuàng)建一個(gè)Callable的線(xiàn)程任務(wù)對(duì)象
Callable call = new MyCallable();
// 4.把Callable任務(wù)對(duì)象包裝成一個(gè)未來(lái)任務(wù)對(duì)象
// -- public FutureTask(Callable<V> callable)
// 未來(lái)任務(wù)對(duì)象是啥,有啥用?
// -- 未來(lái)任務(wù)對(duì)象其實(shí)就是一個(gè)Runnable對(duì)象:這樣就可以被包裝成線(xiàn)程對(duì)象!
// -- 未來(lái)任務(wù)對(duì)象可以在線(xiàn)程執(zhí)行完畢之后去得到線(xiàn)程執(zhí)行的結(jié)果。
FutureTask<String> task = new FutureTask<>(call);
// 5.把未來(lái)任務(wù)對(duì)象包裝成線(xiàn)程對(duì)象
Thread t = new Thread(task);
// 6.啟動(dòng)線(xiàn)程對(duì)象
t.start();
for(int i = 1 ; i <= 10 ; i++ ){
System.out.println(Thread.currentThread().getName()+" => " + i);
}
// 在最后去獲取線(xiàn)程執(zhí)行的結(jié)果,如果線(xiàn)程沒(méi)有結(jié)果,讓出CPU等線(xiàn)程執(zhí)行完再來(lái)取結(jié)果
try {
String rs = task.get(); // 獲取call方法返回的結(jié)果(正常/異常結(jié)果)
System.out.println(rs);
} catch (Exception e) {
e.printStackTrace();
}
}
}
// 1.創(chuàng)建一個(gè)線(xiàn)程任務(wù)類(lèi)實(shí)現(xiàn)Callable接口,申明線(xiàn)程返回的結(jié)果類(lèi)型
class MyCallable implements Callable<String>{
// 2.重寫(xiě)線(xiàn)程任務(wù)類(lèi)的call方法!
@Override
public String call() throws Exception {
// 需求:計(jì)算1-10的和返回
int sum = 0 ;
for(int i = 1 ; i <= 10 ; i++ ){
System.out.println(Thread.currentThread().getName()+" => " + i);
sum+=i;
}
return Thread.currentThread().getName()+"執(zhí)行的結(jié)果是:"+sum;
}
}
優(yōu)點(diǎn): 線(xiàn)程任務(wù)類(lèi)只是實(shí)現(xiàn)了Callable接口,可以繼續(xù)繼承其他類(lèi),而且可以繼續(xù)實(shí)現(xiàn)其他接口(避免了單繼承的局限性)。 同一個(gè)線(xiàn)程任務(wù)對(duì)象可以被包裝成多個(gè)線(xiàn)程對(duì)象,適合多個(gè)多個(gè)線(xiàn)程去共享同一個(gè)資源。實(shí)現(xiàn)解耦操作,線(xiàn)程任務(wù)代碼可以被多個(gè)線(xiàn)程共享,線(xiàn)程任務(wù)代碼和線(xiàn)程獨(dú)立。最關(guān)鍵的是能直接得到線(xiàn)程執(zhí)行的結(jié)果。
到此這篇關(guān)于Java并發(fā)編程之線(xiàn)程創(chuàng)建的文章就介紹到這了,更多相關(guān)Java 線(xiàn)程創(chuàng)建內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Java實(shí)現(xiàn)簡(jiǎn)易學(xué)籍管理系統(tǒng)
這篇文章主要為大家詳細(xì)介紹了Java實(shí)現(xiàn)簡(jiǎn)易學(xué)籍管理系統(tǒng),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-02-02
springboot如何靜態(tài)加載@configurationProperties
這篇文章主要介紹了springboot如何靜態(tài)加載@configurationProperties,本文一個(gè)錯(cuò)誤案例和成功案例結(jié)合實(shí)例代碼給大家介紹的非常詳細(xì),需要的朋友可以參考下2022-07-07
java?random隨機(jī)數(shù)的用法及常見(jiàn)應(yīng)用場(chǎng)景
這篇文章主要給大家介紹了關(guān)于java?random隨機(jī)數(shù)的用法及常見(jiàn)應(yīng)用場(chǎng)景的相關(guān)資料,Java中的Random類(lèi)是用來(lái)生成偽隨機(jī)數(shù)的工具類(lèi),它可以用來(lái)生成隨機(jī)的整數(shù)、浮點(diǎn)數(shù)和布爾值,需要的朋友可以參考下2023-11-11
java編程調(diào)用存儲(chǔ)過(guò)程中得到新增記錄id號(hào)的實(shí)現(xiàn)方法
這篇文章主要介紹了java編程調(diào)用存儲(chǔ)過(guò)程中得到新增記錄id號(hào)的實(shí)現(xiàn)方法,涉及Java數(shù)據(jù)庫(kù)操作中存儲(chǔ)過(guò)程的相關(guān)使用技巧,需要的朋友可以參考下2015-10-10
Java通過(guò)反射訪(fǎng)問(wèn)注解信息的方法示例
這篇文章主要介紹了Java通過(guò)反射訪(fǎng)問(wèn)注解信息的方法,結(jié)合實(shí)例形式分析了java基于反射訪(fǎng)問(wèn)類(lèi)成員方法注解信息的相關(guān)操作技巧,需要的朋友可以參考下2019-08-08

