Java開啟線程的四種方法案例詳解
1、繼承Thread類
/* * 創(chuàng)建步驟如下: * 1,定義Thread類的子類,并重寫該類的run()方法,該run()方法的方法體就代表了線程需要完成的任務(wù)。因此把run方法稱為線程執(zhí)行體。 * 2,創(chuàng)建Thread子類了的實(shí)例,即創(chuàng)建線程對(duì)象。本實(shí)例中是new一個(gè)ExtendThread,即可創(chuàng)建線程對(duì)象,也就是開啟了一個(gè)線程 * 3,調(diào)用線程對(duì)象的start()方法來啟動(dòng)該線程。 * * 調(diào)用示例: * //循環(huán)10次即開啟10個(gè)線程 * for (int i = 0; i < 10; i++) { * ExtendThread extendThread = new ExtendThread(); * extendThread.start(); * } * */
1.1 代碼實(shí)現(xiàn)
package com.zyz.mynative.demo03; /** * @author zyz * @version 1.0 * @data 2023/2/15 15:51 * @Description:繼承Thread類,重寫run方法(不推薦,因?yàn)閖ava的單繼承局限性) */ public class ExtendThread extends Thread { public static void main(String[] args) { ExtendThread thread = new ExtendThread(); thread.start(); } /** * 重寫Thread類的run(),這個(gè)方法稱為線程執(zhí)行體 */ @Override public void run() { doSomething(); } /** * 需要處理的任務(wù) */ public void doSomething() { for (int i = 0; i < 10; i++) { System.out.println(Thread.currentThread().getName() + "執(zhí)行" + i); } } }
1.2 測(cè)試結(jié)果
2、實(shí)現(xiàn)Runnable接口
2.1 方式一:直接實(shí)現(xiàn)Runnable接口
避免單繼承的局限性,方便共享資源,推薦使用
/* * 創(chuàng)建步驟如下: * 1,定義Runnable接口的實(shí)現(xiàn)類,并且實(shí)現(xiàn)run方法,這個(gè)方法同樣是線程執(zhí)行體 * 2,創(chuàng)建Runnable實(shí)現(xiàn)類的實(shí)例,并以此實(shí)例對(duì)象作為Thread的target來創(chuàng)建Thread類,這個(gè)新創(chuàng)建的Thread對(duì)象才是真正的線程對(duì)象,即開啟了新的線程 * 3,調(diào)用線程對(duì)象的start()方法來開啟該線程 * * 調(diào)用示例: * //開啟10個(gè)線程 * for (int i = 0; i < 10; i++) { * Thread thread = new Thread(new RunnableImpl()); * thread.start(); * } * */
2.1.1 代碼實(shí)現(xiàn)
package com.zyz.mynative.demo03; /** * @author zyz * @version 1.0 * @data 2023/2/15 15:57 * @Description: */ public class RunnableImpl implements Runnable { public static void main(String[] args) { RunnableImpl runnable = new RunnableImpl(); Thread thread = new Thread(runnable); thread.start(); /** * 簡(jiǎn)寫 * new Thread(runnable).start(); */ } /** * 實(shí)現(xiàn)Runnable接口的run方法,這個(gè)方法稱為線程執(zhí)行體 * */ @Override public void run() { doSomething(); } /** * 需要處理的任務(wù) * */ private void doSomething(){ for (int i = 0; i < 10; i++) { System.out.println(Thread.currentThread().getName() + "執(zhí)行" + i); } } }
2.1.2 測(cè)試結(jié)果
2.2 方式二:匿名內(nèi)部類
/* * 創(chuàng)建步驟如下: * 匿名內(nèi)部類本質(zhì)上也是一個(gè)類實(shí)現(xiàn)了Runnable接口,重寫了run方法,只不過這個(gè)類沒有名字,直接作為參數(shù)傳入Thread類 * * 調(diào)用示例: * //開啟10個(gè)線程 * for (int i = 0; i < 10; i++) { * Anonymous anonymous =new Anonymous(); * anonymous.myRun(); * } * * */
2.2.1 代碼實(shí)現(xiàn)
package com.zyz.mynative.demo03; /** * @author zyz * @version 1.0 * @data 2023/2/15 15:57 * @Description: */ public class RunnableImpl2 { public static void main(String[] args) { RunnableImpl2 test = new RunnableImpl2(); test.myRun(); } public void myRun(){ new Thread(new Runnable() { @Override public void run() { doSomething(); } }).start(); } /** * 需要處理的任務(wù) * */ private void doSomething(){ for (int i = 0; i < 10; i++) { System.out.println(Thread.currentThread().getName() + "執(zhí)行" + i); } } }
2.2.2 測(cè)試結(jié)果
3、實(shí)現(xiàn)Callable接口
/* * 創(chuàng)建步驟如下: * 1,定義實(shí)現(xiàn)Callable<V>接口的實(shí)現(xiàn)類,實(shí)現(xiàn)call方法,這個(gè)方法是線程執(zhí)行體 * 2,創(chuàng)建Callable<V>實(shí)現(xiàn)類的實(shí)例,借助FutureTask得到線程執(zhí)行的返回值 * 3,將FutureTask的實(shí)例,作為Thread的target來創(chuàng)建Thread類 * 4,調(diào)用start方法,開啟線程 * * 調(diào)用示例: * Callable<String> tc = new CallableImpl(); * FutureTask<String> task = new FutureTask<>(tc); * new Thread(task).start(); * try { * System.out.println(task.get()); * } catch (InterruptedException | ExecutionException e) { * e.printStackTrace(); * } * * 說明: * 1.與使用Runnable相比, Callable功能更強(qiáng)大些 * 2.實(shí)現(xiàn)的call()方法相比run()方法,可以返回值 * 3.方法可以拋出異常 * 4.支持泛型的返回值 * 5.需要借助FutureTask類,比如獲取返回結(jié)果 * Future接口可以對(duì)具體Runnable、Callable任務(wù)的執(zhí)行結(jié)果進(jìn)行取消、查詢是否完成、獲取結(jié)果等。 * FutureTask是Futrue接口的唯一的實(shí)現(xiàn)類 * FutureTask 同時(shí)實(shí)現(xiàn)了Runnable, Future接口。它既可以作為Runnable被線程執(zhí)行,又可以作為Future得到Callable的返回值 * * */
3.1 代碼實(shí)現(xiàn)
package com.zyz.mynative.demo03; import java.util.concurrent.Callable; import java.util.concurrent.ExecutionException; import java.util.concurrent.FutureTask; /** * @author zyz * @version 1.0 * @data 2023/2/15 16:08 * @Description: */ public class CallableImpl implements Callable<String> { public static void main(String[] args) { Callable<String> tc = new CallableImpl(); FutureTask<String> task = new FutureTask<>(tc); new Thread(task).start(); try { System.out.println(task.get()); } catch (InterruptedException | ExecutionException e) { e.printStackTrace(); } } private int ticket = 5; @Override public String call() throws Exception { for (int i = 0; i < 10; i++) { System.out.println(doSomething()); } return "出票任務(wù)完成"; } public String doSomething() { String result = ""; if (this.ticket > 0) { result = "出票成功,ticket=" + this.ticket--; } else { result = "出票失敗,ticket=" + this.ticket; } return result; } }
3.2 測(cè)試結(jié)果
4、創(chuàng)建線程池
/* * 創(chuàng)建步驟如下: * 1,定義Runnable接口的實(shí)現(xiàn)類,或者定義(繼承Runnable接口的類)的實(shí)現(xiàn)類,并且實(shí)現(xiàn)run方法,這個(gè)方法是線程執(zhí)行體 * 2,創(chuàng)建一個(gè)自定義線程個(gè)數(shù)的線程池 * 3,實(shí)例化Runnable接口的實(shí)現(xiàn)類 * 4,將3步的實(shí)例,作為線程池實(shí)例的execute方法的command參數(shù),開啟線程 * 5,關(guān)閉線程池 * * 調(diào)用示例: * ExecutorService pool = Executors.newFixedThreadPool(2); * ThreadPool threadPool = new ThreadPool("AA"); * ThreadPool threadPoo2 = new ThreadPool("BB"); * pool.execute(threadPool); * pool.execute(threadPoo2); * pool.shutdown(); * * 說明: * 示例中創(chuàng)建的是2個(gè)線程的線程池 * execute方法是開啟線程方法,實(shí)參要求是實(shí)現(xiàn)Runnable的類。所以,繼承Thread類的子類也可以以線程池的方式開啟線程 * * */
4.1 代碼實(shí)例
package com.zyz.mynative.demo03; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; /** * @author zyz * @version 1.0 * @data 2023/2/15 16:11 * @Description: */ public class ThreadPool implements Runnable { public static void main(String[] args) { ExecutorService pool = Executors.newFixedThreadPool(2); ThreadPool threadPool = new ThreadPool("AA"); ThreadPool threadPoo2 = new ThreadPool("BB"); pool.execute(threadPool); pool.execute(threadPoo2); pool.shutdown(); } String name; public ThreadPool(String name) { this.name = name; } @Override public void run() { doSomething(); } /** * 需要處理的任務(wù) * */ private void doSomething() { for (int i = 0; i < 10; i++) { System.out.println(Thread.currentThread().getName() + "執(zhí)行" + i + ",name=" + this.name); } } }
4.2 測(cè)試結(jié)果
資料參考:創(chuàng)建線程池的實(shí)現(xiàn)方法
到此這篇關(guān)于Java開啟線程的四種方法的文章就介紹到這了,更多相關(guān)java開啟線程內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

navicatdesignquery.sql.bak系統(tǒng)找不到指定路徑錯(cuò)誤的解決方法

最新IntelliJ IDEA 2021版配置 Tomcat 8.5 的詳細(xì)步驟

如何通過javacv實(shí)現(xiàn)圖片去水印(附代碼)

Java BigDecimal解決double精度丟失的問題

Java大文本并行計(jì)算實(shí)現(xiàn)過程解析

Java獲取接口的所有實(shí)現(xiàn)類方法總結(jié)示例