<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                合規國際互聯網加速 OSASE為企業客戶提供高速穩定SD-WAN國際加速解決方案。 廣告
                ![](https://cdn.zimug.com/wx-zimug.png) # java創建并運行線程的五種方法區別 [TOC] ## 一、前言 熟悉我的朋友可能都知道,我寫的文章偏于應用實戰,絕大多數是為了解決實際生產中遇到的問題。 ![](http://cdn.zimug.com/bebbc017a009d86498361bcca343378d) 上面的這個問題是我的一位小伙伴向我提出的問題,當時由于工作太忙并沒有回復他,那就通過這篇文章回復了。解決應用高并發的問題不是一兩句話能說清楚的,也**不是一兩本書能講明白的**,這里面涉及到知識點比較很多很多,比如:并發編程、應用緩存設計、消息中間件、負載均衡、微服務架構、docker&k8s服務擴容縮容等等,都是為了應對“三高”:高并發、高性能、高可用。 這其中并發編程就是基礎中的基礎,我的CSDN專欄《并發編程》中已經寫了20篇關于java并發編程方面的文章,但我感覺這還僅僅是其中的冰山一角。這個專欄我還會繼續寫下去,這一篇的內容相對基礎:**創建線程的5種方式**。 ## 二、創建并運行線程的四種方法 ### 第一種:繼承Thread類 這種方式是最基礎的一種方式,學過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接口 第二種實現方式仍然很基礎,繼承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接口,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方法調用時也會拋出同樣的異常 ### 第四種:線程池 + execute 從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接口,但運行方式不一樣,使用線程池 ~~~ 從上面的結果中可以看出,線程池中包含五個線程。線程運行完成之后并不銷毀,而是還回到線程池,下一次執行時從線程池中獲取線程資源再次運行。 ### 第五種:線程池 + submit **下面的例子線程池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提供的方法引用,我也寫過很多關于java8的一些有趣的用法,可以看我的CSDN博客專欄。 ~~~ 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接口帶返回值,可以拋出異常 ~~~
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看