您好,登錄后才能下訂單哦!
本篇內(nèi)容主要講解“Java并發(fā)編程之線程怎么創(chuàng)建”,感興趣的朋友不妨來看看。本文介紹的方法操作簡單快捷,實(shí)用性強(qiáng)。下面就讓小編來帶大家學(xué)習(xí)“Java并發(fā)編程之線程怎么創(chuàng)建”吧!
進(jìn)程是代碼在數(shù)據(jù)集合上的一次運(yùn)行活動(dòng),是系統(tǒng)進(jìn)行資源分配和調(diào)度的基本單位,線程則是一個(gè)實(shí)體,一個(gè)進(jìn)程中至少有一個(gè)線程,是CPU調(diào)度和分配的基本單位,進(jìn)程中的多個(gè)線程共享進(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í)輪詢切換依次為每個(gè)進(jìn)程服務(wù),因?yàn)榍袚Q的速度非常快,給我們的感覺這些進(jìn)程在同時(shí)執(zhí)行,這就是并發(fā)性。
我們?cè)谶M(jìn)程中創(chuàng)建線程的方式有三種:
方式一:繼承Thread類的方式
1.定義一個(gè)線程類繼承Thread類。
2.重寫run()方法
3.創(chuàng)建一個(gè)新的線程對(duì)象。
4.調(diào)用線程對(duì)象的start()方法啟動(dòng)線程。
public class ThreadDemo { // 啟動(dòng)后的ThreadDemo當(dāng)成一個(gè)進(jìn)程。 // main方法是由主線程執(zhí)行的,理解成main方法就是一個(gè)主線程 public static void main(String[] args) { // 3.創(chuàng)建一個(gè)線程對(duì)象 Thread t = new MyThread(); // 4.調(diào)用線程對(duì)象的start()方法啟動(dòng)線程,最終還是執(zhí)行run()方法! t.start(); for(int i = 0 ; i < 100 ; i++ ){ System.out.println("main線程輸出:"+i); } } } // 1.定義一個(gè)線程類繼承Thread類。 class MyThread extends Thread{ // 2.重寫run()方法 @Override public void run() { // 線程的執(zhí)行方法。 for(int i = 0 ; i < 100 ; i++ ){ System.out.println("子線程輸出:"+i); } } }
優(yōu)點(diǎn):編碼簡單,在run()方法內(nèi)獲取當(dāng)前線程直接使用this就可以了,無需使用Thread.currentThread()方法。 缺點(diǎn):線程類已經(jīng)繼承了Thread類無法繼承其他類了,功能不能通過繼承拓(單繼承的局限性)。另外任務(wù)與代碼沒有分離,當(dāng)多個(gè)線程執(zhí)行一樣的任務(wù)時(shí)需要多份任務(wù)代碼。
小結(jié):
線程類是繼承了Thread的類。
啟動(dòng)線程必須調(diào)用start()方法。
多線程是并發(fā)搶占CPU執(zhí)行,所以在執(zhí)行的過程中會(huì)出現(xiàn)并發(fā)隨機(jī)性
方式二:實(shí)現(xiàn)Runnable接口的方式。
1.創(chuàng)建一個(gè)線程任務(wù)類實(shí)現(xiàn)Runnable接口。
2.重寫run()方法
3.創(chuàng)建一個(gè)線程任務(wù)對(duì)象。
4.把線程任務(wù)對(duì)象包裝成線程對(duì)象
5.調(diào)用線程對(duì)象的start()方法啟動(dòng)線程。
public class ThreadDemo { public static void main(String[] args) { // 3.創(chuàng)建一個(gè)線程任務(wù)對(duì)象(注意:線程任務(wù)對(duì)象不是線程對(duì)象,只是執(zhí)行線程的任務(wù)的) Runnable target = new MyRunnable(); // 4.把線程任務(wù)對(duì)象包裝成線程對(duì)象.且可以指定線程名稱 // Thread t = new Thread(target); Thread t = new Thread(target,"1號(hào)線程"); // 5.調(diào)用線程對(duì)象的start()方法啟動(dòng)線程 t.start(); Thread t2 = new Thread(target); // 調(diào)用線程對(duì)象的start()方法啟動(dòng)線程 t2.start(); for(int i = 0 ; i < 10 ; i++ ){ System.out.println(Thread.currentThread().getName()+"==>"+i); } } } // 1.創(chuàng)建一個(gè)線程任務(wù)類實(shí)現(xiàn)Runnable接口。 class MyRunnable implements Runnable{ // 2.重寫run()方法 @Override public void run() { for(int i = 0 ; i < 10 ; i++ ){ System.out.println(Thread.currentThread().getName()+"==>"+i); } } }
優(yōu)點(diǎn):
線程任務(wù)類只是實(shí)現(xiàn)了Runnable接口,可以繼續(xù)繼承其他類,而且可以繼續(xù)實(shí)現(xiàn)其他接口(避免了單繼承的局限性)。 同一個(gè)線程任務(wù)對(duì)象可以被包裝成多個(gè)線程對(duì)象,適合多個(gè)多個(gè)線程去共享同一個(gè)資源。實(shí)現(xiàn)解耦操作,線程任務(wù)代碼可以被多個(gè)線程共享,線程任務(wù)代碼和線程獨(dú)立。
方法三:實(shí)現(xiàn)Callable接口
1.定義一個(gè)線程任務(wù)類實(shí)現(xiàn)Callable接口 , 申明線程執(zhí)行的結(jié)果類型。
2.重寫線程任務(wù)類的call方法,這個(gè)方法可以直接返回執(zhí)行的結(jié)果。
3.創(chuàng)建一個(gè)Callable的線程任務(wù)對(duì)象。
4.把Callable的線程任務(wù)對(duì)象包裝成一個(gè)FutureTask對(duì)象。
5.把FutureTask對(duì)象包裝成線程對(duì)象。
6.調(diào)用線程的start()方法啟動(dòng)線程 。
public class ThreadDemo { public static void main(String[] args) { // 3.創(chuàng)建一個(gè)Callable的線程任務(wù)對(duì)象 Callable call = new MyCallable(); // 4.把Callable任務(wù)對(duì)象包裝成一個(gè)未來任務(wù)對(duì)象 // -- public FutureTask(Callable<V> callable) // 未來任務(wù)對(duì)象是啥,有啥用? // -- 未來任務(wù)對(duì)象其實(shí)就是一個(gè)Runnable對(duì)象:這樣就可以被包裝成線程對(duì)象! // -- 未來任務(wù)對(duì)象可以在線程執(zhí)行完畢之后去得到線程執(zhí)行的結(jié)果。 FutureTask<String> task = new FutureTask<>(call); // 5.把未來任務(wù)對(duì)象包裝成線程對(duì)象 Thread t = new Thread(task); // 6.啟動(dòng)線程對(duì)象 t.start(); for(int i = 1 ; i <= 10 ; i++ ){ System.out.println(Thread.currentThread().getName()+" => " + i); } // 在最后去獲取線程執(zhí)行的結(jié)果,如果線程沒有結(jié)果,讓出CPU等線程執(zhí)行完再來取結(jié)果 try { String rs = task.get(); // 獲取call方法返回的結(jié)果(正常/異常結(jié)果) System.out.println(rs); } catch (Exception e) { e.printStackTrace(); } } } // 1.創(chuàng)建一個(gè)線程任務(wù)類實(shí)現(xiàn)Callable接口,申明線程返回的結(jié)果類型 class MyCallable implements Callable<String>{ // 2.重寫線程任務(wù)類的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): 線程任務(wù)類只是實(shí)現(xiàn)了Callable接口,可以繼續(xù)繼承其他類,而且可以繼續(xù)實(shí)現(xiàn)其他接口(避免了單繼承的局限性)。 同一個(gè)線程任務(wù)對(duì)象可以被包裝成多個(gè)線程對(duì)象,適合多個(gè)多個(gè)線程去共享同一個(gè)資源。實(shí)現(xiàn)解耦操作,線程任務(wù)代碼可以被多個(gè)線程共享,線程任務(wù)代碼和線程獨(dú)立。最關(guān)鍵的是能直接得到線程執(zhí)行的結(jié)果。
到此,相信大家對(duì)“Java并發(fā)編程之線程怎么創(chuàng)建”有了更深的了解,不妨來實(shí)際操作一番吧!這里是億速云網(wǎng)站,更多相關(guān)內(nèi)容可以進(jìn)入相關(guān)頻道進(jìn)行查詢,關(guān)注我們,繼續(xù)學(xué)習(xí)!
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。