您好,登錄后才能下訂單哦!
這篇文章主要介紹“Java并發編程如何創建并運行線程”,在日常操作中,相信很多人在Java并發編程如何創建并運行線程問題上存在疑惑,小編查閱了各式資料,整理出簡單好用的操作方法,希望對大家解答”Java并發編程如何創建并運行線程”的疑惑有所幫助!接下來,請跟著小編一起來學習吧!
這種方式是最基礎的一種方式,學過java的朋友都知道,不做贅述。需要注意的是:覆蓋實現使用的是run方法,運行線程是start方法。
public class FirstWay extends Thread { @Override public void run() { System.out.println("第一種實現線程的方式:繼承Thread類"); } //模擬測試 public static void main(String[] args) { new FirstWay().start(); } }
第二種實現方式仍然很基礎,繼承Runnable接口,重寫run方法實現線程運行邏輯。需要注意的:運行線程需要套一層new Thread
。
public class SecondWay implements Runnable{ @Override public void run() { System.out.println("第二種實現線程的方式:實現Runnable接口"); } //模擬測試 public static void main(String[] args) { new Thread(new SecondWay()).start(); } }
第三種方式是實現Callable接口,Callable接口與Runable接口都能實現線程。
public class ThirdWay implements Callable<String> { @Override public String call() throws Exception { System.out.println("第三種實現線程的方式:實現Callable接口"); return "Callable接口帶返回值,可以拋出異常"; } //模擬測試 public static void main(String[] args) throws ExecutionException, InterruptedException { FutureTask<String> futureTask = new FutureTask<>(new ThirdWay()); new Thread(futureTask).start(); //阻塞方法,獲取call方法返回值 System.out.println(futureTask.get()); //打印:Callable接口帶返回值,可以拋出異常 } }
區別如下:
Callable接口實現線程方法是call, Runable接口實現線程方法是run
Callable有返回值, Runable接口不能有返回值
Callable接口方法call返回值可以設置泛型,如下例子中使用String數據類型
Callable接口方法call方法可以拋出異常,Runable接口run方法不可以拋出異常
Callable接口方法通過new Thread(futureTask).start()
運行,FutureTask的get方法可以獲取Callable接口方法call方法的返回值
如果Callable接口方法call方法異常,在FutureTask的get方法調用時也會拋出同樣的異常
從JDK5版本開始,java默認提供了線程池的支持,用線程池的方式運行線程可以避免線程的無限擴張導致應用宕機,同時也節省了線程頻繁創建與銷毀的資源與時間成本。
public class FourthWay implements Runnable{ @Override public void run() { System.out.println(Thread.currentThread().getName() + ":實現線程的方式Runnable接口,但運行方式不一樣,使用線程池"); } public static void main(String[] args) { //創建一個固定大小的線程池 ExecutorService threadPool = Executors.newFixedThreadPool(5); for(int i = 0;i < 10;i++){ threadPool.execute(new FourthWay()); } } }
線程池ExecutorService使用execute方法運行Runnable接口run方法的線程實現,execute方法與run方法的共同特點是沒有返回值。
pool-1-thread-5:實現線程的方式Runnable接口,但運行方式不一樣,使用線程池 pool-1-thread-2:實現線程的方式Runnable接口,但運行方式不一樣,使用線程池 pool-1-thread-4:實現線程的方式Runnable接口,但運行方式不一樣,使用線程池 pool-1-thread-4:實現線程的方式Runnable接口,但運行方式不一樣,使用線程池 pool-1-thread-4:實現線程的方式Runnable接口,但運行方式不一樣,使用線程池 pool-1-thread-1:實現線程的方式Runnable接口,但運行方式不一樣,使用線程池 pool-1-thread-4:實現線程的方式Runnable接口,但運行方式不一樣,使用線程池 pool-1-thread-3:實現線程的方式Runnable接口,但運行方式不一樣,使用線程池 pool-1-thread-2:實現線程的方式Runnable接口,但運行方式不一樣,使用線程池 pool-1-thread-5:實現線程的方式Runnable接口,但運行方式不一樣,使用線程池
從上面的結果中可以看出,線程池中包含五個線程。線程運行完成之后并不銷毀,而是還回到線程池,下一次執行時從線程池中獲取線程資源再次運行。
下面的例子線程池ExecutorService使用submit方法運行Callable接口call方法的線程實現,submit方法與call方法的共同特點是存在返回值。
Callable接口call方法的返回值可以由泛型定義
ExecutorService線程池submit方法的返回值是Future
Future的get方法可以獲取call方法的返回值,同時如果call方法拋出異常,Future的get方法也會拋出異常。
public class FifthWay implements Callable<String> { @Override public String call() throws Exception { return Thread.currentThread().getName() + ":Callable接口帶返回值,可以拋出異常"; } //模擬測試 public static void main(String[] args) throws ExecutionException, InterruptedException { //保存多線程執行結果 List<String> retList = new ArrayList<>(); //創建一個固定大小的線程池 ExecutorService threadPool = Executors.newFixedThreadPool(5); for(int i = 0;i < 10;i++){ Future<String> future = threadPool.submit(new FifthWay()); retList.add(future.get()); } //java8 語法,打印retlist retList.forEach(System.out::println); } }
上文代碼中有一個小小的語法糖,retList.forEach(System.out::println);
是java8提供的方法引用
pool-1-thread-1:Callable接口帶返回值,可以拋出異常 pool-1-thread-2:Callable接口帶返回值,可以拋出異常 pool-1-thread-3:Callable接口帶返回值,可以拋出異常 pool-1-thread-4:Callable接口帶返回值,可以拋出異常 pool-1-thread-5:Callable接口帶返回值,可以拋出異常 pool-1-thread-1:Callable接口帶返回值,可以拋出異常 pool-1-thread-2:Callable接口帶返回值,可以拋出異常 pool-1-thread-3:Callable接口帶返回值,可以拋出異常 pool-1-thread-4:Callable接口帶返回值,可以拋出異常 pool-1-thread-5:Callable接口帶返回值,可以拋出異常
到此,關于“Java并發編程如何創建并運行線程”的學習就結束了,希望能夠解決大家的疑惑。理論與實踐的搭配能更好的幫助大家學習,快去試試吧!若想繼續學習更多相關知識,請繼續關注億速云網站,小編會繼續努力為大家帶來更多實用的文章!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。