<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          面試官:線程池執(zhí)行過程中遇到異常會發(fā)生什么,怎樣處理?

          共 7900字,需瀏覽 16分鐘

           ·

          2021-10-14 00:05

          線程遇到未處理的異常就結(jié)束了

          這個好理解,當(dāng)線程出現(xiàn)未捕獲異常的時候就執(zhí)行不下去了,留給它的就是垃圾回收了。

          線程池中線程頻繁出現(xiàn)未捕獲異常

          ?{???try?{????Thread.sleep(100);???}?catch?(InterruptedException?e)?{????e.printStackTrace();???}???threadPoolExecutor.execute(()?->?{?????int?j?=?1/0;??});});?}}新建一個只有一個線程的線程池,每隔0.1s提交一個任務(wù),任務(wù)中是一個1/0的計算。Exception?in?thread?"customThread?0"?java.lang.ArithmeticException:?/?by?zero?at?thread.ThreadExecutor.lambda$null$0(ThreadExecutor.java:25)?at?java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)?at?java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)?at?java.lang.Thread.run(Thread.java:748)Exception?in?thread?"customThread?1"?java.lang.ArithmeticException:?/?by?zero?at?thread.ThreadExecutor.lambda$null$0(ThreadExecutor.java:25)?at?java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)?at?java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)?at?java.lang.Thread.run(Thread.java:748)Exception?in?thread?"customThread?2"?java.lang.ArithmeticException:?/?by?zero?at?thread.ThreadExecutor.lambda$null$0(ThreadExecutor.java:25)?at?java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)?at?java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)?at?java.lang.Thread.run(Thread.java:748)Exception?in?thread?"customThread?3"?java.lang.ArithmeticException:?/?by?zero?at?thread.ThreadExecutor.lambda$null$0(ThreadExecutor.java:25)?at?java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)?at?java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)?at?java.lang.Thread.run(Thread.java:748)Exception?in?thread?"customThread?4"?java.lang.ArithmeticException:?/?by?zero?at?thread.ThreadExecutor.lambda$null$0(ThreadExecutor.java:25)?at?java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)?at?java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)?at?java.lang.Thread.run(Thread.java:748)Exception?in?thread?"customThread?5"?java.lang.ArithmeticException:?/?by?zero?at?thread.ThreadExecutor.lambda$null$0(ThreadExecutor.java:25)?at?java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)?at?java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)?at?java.lang.Thread.run(Thread.java:748)可見每次執(zhí)行的線程都不一樣,之前的線程都沒有復(fù)用。原因是因為出現(xiàn)了未捕獲的異常。我們把異常捕獲試試:public?class?ThreadExecutor?{?private?ThreadPoolExecutor?threadPoolExecutor?=?new?ThreadPoolExecutor(1,?1,?60,?TimeUnit.SECONDS,???new?ArrayBlockingQueue<>(200),?new?ThreadFactoryBuilder().setNameFormat("customThread?%d").build());?@Test?public?void?test()?{??IntStream.rangeClosed(1,?5).forEach(i?->?{???try?{????Thread.sleep(100);???}?catch?(InterruptedException?e)?{????e.printStackTrace();???}???threadPoolExecutor.execute(()?->?{????try?{?????int?j?=?1?/?0;????}?catch?(Exception?e)?{?????System.out.println(Thread.currentThread().getName()?+"?"+?e.getMessage());????}???});??});?}}customThread?0?/?by?zerocustomThread?0?/?by?zerocustomThread?0?/?by?zerocustomThread?0?/?by?zerocustomThread?0?/?by?zero可見當(dāng)異常捕獲了,線程就可以復(fù)用了。" data-itemshowtype="0" tab="innerlink" data-linktype="2" data-darkmode-color-16340410061459="rgb(163, 163, 163)" data-darkmode-original-color-16340410061459="#fff|rgb(63, 63, 63)|rgb(74, 74, 74)|rgb(58, 58, 58)" data-style="color: rgb(58, 58, 58);" class="js_darkmode__7" hasload="1" wah-hotarea="click" style="outline: 0px; color: rgb(58, 58, 58); cursor: pointer; max-width: 100%; visibility: visible; box-sizing: border-box !important; word-wrap: break-word !important;">當(dāng)線程池中線程頻繁出現(xiàn)未捕獲的異常,那線程的復(fù)用率就大大降低了,需要不斷地創(chuàng)建新線程。

          ?{???try?{????Thread.sleep(100);???}?catch?(InterruptedException?e)?{????e.printStackTrace();???}???threadPoolExecutor.execute(()?->?{?????int?j?=?1/0;??});});?}}新建一個只有一個線程的線程池,每隔0.1s提交一個任務(wù),任務(wù)中是一個1/0的計算。Exception?in?thread?"customThread?0"?java.lang.ArithmeticException:?/?by?zero?at?thread.ThreadExecutor.lambda$null$0(ThreadExecutor.java:25)?at?java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)?at?java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)?at?java.lang.Thread.run(Thread.java:748)Exception?in?thread?"customThread?1"?java.lang.ArithmeticException:?/?by?zero?at?thread.ThreadExecutor.lambda$null$0(ThreadExecutor.java:25)?at?java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)?at?java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)?at?java.lang.Thread.run(Thread.java:748)Exception?in?thread?"customThread?2"?java.lang.ArithmeticException:?/?by?zero?at?thread.ThreadExecutor.lambda$null$0(ThreadExecutor.java:25)?at?java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)?at?java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)?at?java.lang.Thread.run(Thread.java:748)Exception?in?thread?"customThread?3"?java.lang.ArithmeticException:?/?by?zero?at?thread.ThreadExecutor.lambda$null$0(ThreadExecutor.java:25)?at?java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)?at?java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)?at?java.lang.Thread.run(Thread.java:748)Exception?in?thread?"customThread?4"?java.lang.ArithmeticException:?/?by?zero?at?thread.ThreadExecutor.lambda$null$0(ThreadExecutor.java:25)?at?java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)?at?java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)?at?java.lang.Thread.run(Thread.java:748)Exception?in?thread?"customThread?5"?java.lang.ArithmeticException:?/?by?zero?at?thread.ThreadExecutor.lambda$null$0(ThreadExecutor.java:25)?at?java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)?at?java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)?at?java.lang.Thread.run(Thread.java:748)可見每次執(zhí)行的線程都不一樣,之前的線程都沒有復(fù)用。原因是因為出現(xiàn)了未捕獲的異常。我們把異常捕獲試試:public?class?ThreadExecutor?{?private?ThreadPoolExecutor?threadPoolExecutor?=?new?ThreadPoolExecutor(1,?1,?60,?TimeUnit.SECONDS,???new?ArrayBlockingQueue<>(200),?new?ThreadFactoryBuilder().setNameFormat("customThread?%d").build());?@Test?public?void?test()?{??IntStream.rangeClosed(1,?5).forEach(i?->?{???try?{????Thread.sleep(100);???}?catch?(InterruptedException?e)?{????e.printStackTrace();???}???threadPoolExecutor.execute(()?->?{????try?{?????int?j?=?1?/?0;????}?catch?(Exception?e)?{?????System.out.println(Thread.currentThread().getName()?+"?"+?e.getMessage());????}???});??});?}}customThread?0?/?by?zerocustomThread?0?/?by?zerocustomThread?0?/?by?zerocustomThread?0?/?by?zerocustomThread?0?/?by?zero可見當(dāng)異常捕獲了,線程就可以復(fù)用了。" data-itemshowtype="0" tab="innerlink" data-linktype="2" data-darkmode-color-16340410061459="rgb(156, 156, 156)" data-darkmode-original-color-16340410061459="#fff|rgb(63, 63, 63)|rgb(74, 74, 74)" wah-hotarea="click" hasload="1" style="outline: 0px; color: rgb(125, 144, 169); cursor: pointer; max-width: 100%; box-sizing: border-box !important; word-wrap: break-word !important;">做個實驗:

          ?{???try?{????Thread.sleep(100);???}?catch?(InterruptedException?e)?{????e.printStackTrace();???}???threadPoolExecutor.execute(()?->?{?????int?j?=?1/0;??});});?}}新建一個只有一個線程的線程池,每隔0.1s提交一個任務(wù),任務(wù)中是一個1/0的計算。Exception?in?thread?"customThread?0"?java.lang.ArithmeticException:?/?by?zero?at?thread.ThreadExecutor.lambda$null$0(ThreadExecutor.java:25)?at?java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)?at?java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)?at?java.lang.Thread.run(Thread.java:748)Exception?in?thread?"customThread?1"?java.lang.ArithmeticException:?/?by?zero?at?thread.ThreadExecutor.lambda$null$0(ThreadExecutor.java:25)?at?java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)?at?java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)?at?java.lang.Thread.run(Thread.java:748)Exception?in?thread?"customThread?2"?java.lang.ArithmeticException:?/?by?zero?at?thread.ThreadExecutor.lambda$null$0(ThreadExecutor.java:25)?at?java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)?at?java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)?at?java.lang.Thread.run(Thread.java:748)Exception?in?thread?"customThread?3"?java.lang.ArithmeticException:?/?by?zero?at?thread.ThreadExecutor.lambda$null$0(ThreadExecutor.java:25)?at?java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)?at?java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)?at?java.lang.Thread.run(Thread.java:748)Exception?in?thread?"customThread?4"?java.lang.ArithmeticException:?/?by?zero?at?thread.ThreadExecutor.lambda$null$0(ThreadExecutor.java:25)?at?java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)?at?java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)?at?java.lang.Thread.run(Thread.java:748)Exception?in?thread?"customThread?5"?java.lang.ArithmeticException:?/?by?zero?at?thread.ThreadExecutor.lambda$null$0(ThreadExecutor.java:25)?at?java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)?at?java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)?at?java.lang.Thread.run(Thread.java:748)可見每次執(zhí)行的線程都不一樣,之前的線程都沒有復(fù)用。原因是因為出現(xiàn)了未捕獲的異常。我們把異常捕獲試試:public?class?ThreadExecutor?{?private?ThreadPoolExecutor?threadPoolExecutor?=?new?ThreadPoolExecutor(1,?1,?60,?TimeUnit.SECONDS,???new?ArrayBlockingQueue<>(200),?new?ThreadFactoryBuilder().setNameFormat("customThread?%d").build());?@Test?public?void?test()?{??IntStream.rangeClosed(1,?5).forEach(i?->?{???try?{????Thread.sleep(100);???}?catch?(InterruptedException?e)?{????e.printStackTrace();???}???threadPoolExecutor.execute(()?->?{????try?{?????int?j?=?1?/?0;????}?catch?(Exception?e)?{?????System.out.println(Thread.currentThread().getName()?+"?"+?e.getMessage());????}???});??});?}}customThread?0?/?by?zerocustomThread?0?/?by?zerocustomThread?0?/?by?zerocustomThread?0?/?by?zerocustomThread?0?/?by?zero可見當(dāng)異常捕獲了,線程就可以復(fù)用了。" data-itemshowtype="0" tab="innerlink" data-linktype="2" data-darkmode-color-16340410061459="rgb(163, 163, 163)" data-darkmode-original-color-16340410061459="#fff|rgb(63, 63, 63)" wah-hotarea="click" hasload="1" style="outline: 0px; color: rgb(125, 144, 169); cursor: pointer; max-width: 100%; box-sizing: border-box !important; word-wrap: break-word !important;">public?class?ThreadExecutor?{

          ?private?ThreadPoolExecutor?threadPoolExecutor?=?new?ThreadPoolExecutor(1,?1,?60,?TimeUnit.SECONDS,
          ???new?ArrayBlockingQueue<>(200),?new?ThreadFactoryBuilder().setNameFormat("customThread?%d").build());

          ?@Test
          ?public?void?test()?{
          ??IntStream.rangeClosed(1,?5).forEach(i?->?{
          ???try?{
          ????Thread.sleep(100);
          ???}?catch?(InterruptedException?e)?{
          ????e.printStackTrace();
          ???}
          ???threadPoolExecutor.execute(()?->?{
          ?????int?j?=?1/0;
          ??});});
          ?}
          }

          ?{???try?{????Thread.sleep(100);???}?catch?(InterruptedException?e)?{????e.printStackTrace();???}???threadPoolExecutor.execute(()?->?{?????int?j?=?1/0;??});});?}}新建一個只有一個線程的線程池,每隔0.1s提交一個任務(wù),任務(wù)中是一個1/0的計算。Exception?in?thread?"customThread?0"?java.lang.ArithmeticException:?/?by?zero?at?thread.ThreadExecutor.lambda$null$0(ThreadExecutor.java:25)?at?java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)?at?java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)?at?java.lang.Thread.run(Thread.java:748)Exception?in?thread?"customThread?1"?java.lang.ArithmeticException:?/?by?zero?at?thread.ThreadExecutor.lambda$null$0(ThreadExecutor.java:25)?at?java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)?at?java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)?at?java.lang.Thread.run(Thread.java:748)Exception?in?thread?"customThread?2"?java.lang.ArithmeticException:?/?by?zero?at?thread.ThreadExecutor.lambda$null$0(ThreadExecutor.java:25)?at?java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)?at?java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)?at?java.lang.Thread.run(Thread.java:748)Exception?in?thread?"customThread?3"?java.lang.ArithmeticException:?/?by?zero?at?thread.ThreadExecutor.lambda$null$0(ThreadExecutor.java:25)?at?java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)?at?java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)?at?java.lang.Thread.run(Thread.java:748)Exception?in?thread?"customThread?4"?java.lang.ArithmeticException:?/?by?zero?at?thread.ThreadExecutor.lambda$null$0(ThreadExecutor.java:25)?at?java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)?at?java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)?at?java.lang.Thread.run(Thread.java:748)Exception?in?thread?"customThread?5"?java.lang.ArithmeticException:?/?by?zero?at?thread.ThreadExecutor.lambda$null$0(ThreadExecutor.java:25)?at?java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)?at?java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)?at?java.lang.Thread.run(Thread.java:748)可見每次執(zhí)行的線程都不一樣,之前的線程都沒有復(fù)用。原因是因為出現(xiàn)了未捕獲的異常。我們把異常捕獲試試:public?class?ThreadExecutor?{?private?ThreadPoolExecutor?threadPoolExecutor?=?new?ThreadPoolExecutor(1,?1,?60,?TimeUnit.SECONDS,???new?ArrayBlockingQueue<>(200),?new?ThreadFactoryBuilder().setNameFormat("customThread?%d").build());?@Test?public?void?test()?{??IntStream.rangeClosed(1,?5).forEach(i?->?{???try?{????Thread.sleep(100);???}?catch?(InterruptedException?e)?{????e.printStackTrace();???}???threadPoolExecutor.execute(()?->?{????try?{?????int?j?=?1?/?0;????}?catch?(Exception?e)?{?????System.out.println(Thread.currentThread().getName()?+"?"+?e.getMessage());????}???});??});?}}customThread?0?/?by?zerocustomThread?0?/?by?zerocustomThread?0?/?by?zerocustomThread?0?/?by?zerocustomThread?0?/?by?zero可見當(dāng)異常捕獲了,線程就可以復(fù)用了。" data-itemshowtype="0" tab="innerlink" data-linktype="2" data-darkmode-color-16340410061459="rgb(156, 156, 156)" data-darkmode-original-color-16340410061459="#fff|rgb(63, 63, 63)|rgb(74, 74, 74)" wah-hotarea="click" hasload="1" style="outline: 0px; color: rgb(125, 144, 169); cursor: pointer; max-width: 100%; box-sizing: border-box !important; word-wrap: break-word !important;">新建一個只有一個線程的線程池,每隔0.1s提交一個任務(wù),任務(wù)中是一個1/0的計算。

          ?{???try?{????Thread.sleep(100);???}?catch?(InterruptedException?e)?{????e.printStackTrace();???}???threadPoolExecutor.execute(()?->?{?????int?j?=?1/0;??});});?}}新建一個只有一個線程的線程池,每隔0.1s提交一個任務(wù),任務(wù)中是一個1/0的計算。Exception?in?thread?"customThread?0"?java.lang.ArithmeticException:?/?by?zero?at?thread.ThreadExecutor.lambda$null$0(ThreadExecutor.java:25)?at?java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)?at?java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)?at?java.lang.Thread.run(Thread.java:748)Exception?in?thread?"customThread?1"?java.lang.ArithmeticException:?/?by?zero?at?thread.ThreadExecutor.lambda$null$0(ThreadExecutor.java:25)?at?java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)?at?java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)?at?java.lang.Thread.run(Thread.java:748)Exception?in?thread?"customThread?2"?java.lang.ArithmeticException:?/?by?zero?at?thread.ThreadExecutor.lambda$null$0(ThreadExecutor.java:25)?at?java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)?at?java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)?at?java.lang.Thread.run(Thread.java:748)Exception?in?thread?"customThread?3"?java.lang.ArithmeticException:?/?by?zero?at?thread.ThreadExecutor.lambda$null$0(ThreadExecutor.java:25)?at?java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)?at?java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)?at?java.lang.Thread.run(Thread.java:748)Exception?in?thread?"customThread?4"?java.lang.ArithmeticException:?/?by?zero?at?thread.ThreadExecutor.lambda$null$0(ThreadExecutor.java:25)?at?java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)?at?java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)?at?java.lang.Thread.run(Thread.java:748)Exception?in?thread?"customThread?5"?java.lang.ArithmeticException:?/?by?zero?at?thread.ThreadExecutor.lambda$null$0(ThreadExecutor.java:25)?at?java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)?at?java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)?at?java.lang.Thread.run(Thread.java:748)可見每次執(zhí)行的線程都不一樣,之前的線程都沒有復(fù)用。原因是因為出現(xiàn)了未捕獲的異常。我們把異常捕獲試試:public?class?ThreadExecutor?{?private?ThreadPoolExecutor?threadPoolExecutor?=?new?ThreadPoolExecutor(1,?1,?60,?TimeUnit.SECONDS,???new?ArrayBlockingQueue<>(200),?new?ThreadFactoryBuilder().setNameFormat("customThread?%d").build());?@Test?public?void?test()?{??IntStream.rangeClosed(1,?5).forEach(i?->?{???try?{????Thread.sleep(100);???}?catch?(InterruptedException?e)?{????e.printStackTrace();???}???threadPoolExecutor.execute(()?->?{????try?{?????int?j?=?1?/?0;????}?catch?(Exception?e)?{?????System.out.println(Thread.currentThread().getName()?+"?"+?e.getMessage());????}???});??});?}}customThread?0?/?by?zerocustomThread?0?/?by?zerocustomThread?0?/?by?zerocustomThread?0?/?by?zerocustomThread?0?/?by?zero可見當(dāng)異常捕獲了,線程就可以復(fù)用了。" data-itemshowtype="0" tab="innerlink" data-linktype="2" data-darkmode-color-16340410061459="rgb(163, 163, 163)" data-darkmode-original-color-16340410061459="#fff|rgb(63, 63, 63)" wah-hotarea="click" hasload="1" style="outline: 0px; color: rgb(125, 144, 169); cursor: pointer; max-width: 100%; box-sizing: border-box !important; word-wrap: break-word !important;">Exception?in?thread?"customThread?0"?java.lang.ArithmeticException:?/?by?zero
          ?at?thread.ThreadExecutor.lambda$null$0(ThreadExecutor.java:25)
          ?at?java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
          ?at?java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
          ?at?java.lang.Thread.run(Thread.java:748)
          Exception?in?thread?"customThread?1"?java.lang.ArithmeticException:?/?by?zero
          ?at?thread.ThreadExecutor.lambda$null$0(ThreadExecutor.java:25)
          ?at?java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
          ?at?java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
          ?at?java.lang.Thread.run(Thread.java:748)
          Exception?in?thread?"customThread?2"?java.lang.ArithmeticException:?/?by?zero
          ?at?thread.ThreadExecutor.lambda$null$0(ThreadExecutor.java:25)
          ?at?java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
          ?at?java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
          ?at?java.lang.Thread.run(Thread.java:748)
          Exception?in?thread?"customThread?3"?java.lang.ArithmeticException:?/?by?zero
          ?at?thread.ThreadExecutor.lambda$null$0(ThreadExecutor.java:25)
          ?at?java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
          ?at?java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
          ?at?java.lang.Thread.run(Thread.java:748)
          Exception?in?thread?"customThread?4"?java.lang.ArithmeticException:?/?by?zero
          ?at?thread.ThreadExecutor.lambda$null$0(ThreadExecutor.java:25)
          ?at?java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
          ?at?java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
          ?at?java.lang.Thread.run(Thread.java:748)
          Exception?in?thread?"customThread?5"?java.lang.ArithmeticException:?/?by?zero
          ?at?thread.ThreadExecutor.lambda$null$0(ThreadExecutor.java:25)
          ?at?java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
          ?at?java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
          ?at?java.lang.Thread.run(Thread.java:748)

          ?{???try?{????Thread.sleep(100);???}?catch?(InterruptedException?e)?{????e.printStackTrace();???}???threadPoolExecutor.execute(()?->?{?????int?j?=?1/0;??});});?}}新建一個只有一個線程的線程池,每隔0.1s提交一個任務(wù),任務(wù)中是一個1/0的計算。Exception?in?thread?"customThread?0"?java.lang.ArithmeticException:?/?by?zero?at?thread.ThreadExecutor.lambda$null$0(ThreadExecutor.java:25)?at?java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)?at?java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)?at?java.lang.Thread.run(Thread.java:748)Exception?in?thread?"customThread?1"?java.lang.ArithmeticException:?/?by?zero?at?thread.ThreadExecutor.lambda$null$0(ThreadExecutor.java:25)?at?java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)?at?java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)?at?java.lang.Thread.run(Thread.java:748)Exception?in?thread?"customThread?2"?java.lang.ArithmeticException:?/?by?zero?at?thread.ThreadExecutor.lambda$null$0(ThreadExecutor.java:25)?at?java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)?at?java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)?at?java.lang.Thread.run(Thread.java:748)Exception?in?thread?"customThread?3"?java.lang.ArithmeticException:?/?by?zero?at?thread.ThreadExecutor.lambda$null$0(ThreadExecutor.java:25)?at?java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)?at?java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)?at?java.lang.Thread.run(Thread.java:748)Exception?in?thread?"customThread?4"?java.lang.ArithmeticException:?/?by?zero?at?thread.ThreadExecutor.lambda$null$0(ThreadExecutor.java:25)?at?java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)?at?java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)?at?java.lang.Thread.run(Thread.java:748)Exception?in?thread?"customThread?5"?java.lang.ArithmeticException:?/?by?zero?at?thread.ThreadExecutor.lambda$null$0(ThreadExecutor.java:25)?at?java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)?at?java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)?at?java.lang.Thread.run(Thread.java:748)可見每次執(zhí)行的線程都不一樣,之前的線程都沒有復(fù)用。原因是因為出現(xiàn)了未捕獲的異常。我們把異常捕獲試試:public?class?ThreadExecutor?{?private?ThreadPoolExecutor?threadPoolExecutor?=?new?ThreadPoolExecutor(1,?1,?60,?TimeUnit.SECONDS,???new?ArrayBlockingQueue<>(200),?new?ThreadFactoryBuilder().setNameFormat("customThread?%d").build());?@Test?public?void?test()?{??IntStream.rangeClosed(1,?5).forEach(i?->?{???try?{????Thread.sleep(100);???}?catch?(InterruptedException?e)?{????e.printStackTrace();???}???threadPoolExecutor.execute(()?->?{????try?{?????int?j?=?1?/?0;????}?catch?(Exception?e)?{?????System.out.println(Thread.currentThread().getName()?+"?"+?e.getMessage());????}???});??});?}}customThread?0?/?by?zerocustomThread?0?/?by?zerocustomThread?0?/?by?zerocustomThread?0?/?by?zerocustomThread?0?/?by?zero可見當(dāng)異常捕獲了,線程就可以復(fù)用了。" data-itemshowtype="0" tab="innerlink" data-linktype="2" data-darkmode-color-16340410061459="rgb(163, 163, 163)" data-darkmode-original-color-16340410061459="#fff|rgb(63, 63, 63)|rgb(74, 74, 74)|rgb(58, 58, 58)" data-style="color: rgb(58, 58, 58);" class="js_darkmode__16" wah-hotarea="click" hasload="1" style="outline: 0px; color: rgb(58, 58, 58); cursor: pointer; max-width: 100%; box-sizing: border-box !important; word-wrap: break-word !important;">可見每次執(zhí)行的線程都不一樣,之前的線程都沒有復(fù)用。原因是因為出現(xiàn)了未捕獲的異常。

          ?{???try?{????Thread.sleep(100);???}?catch?(InterruptedException?e)?{????e.printStackTrace();???}???threadPoolExecutor.execute(()?->?{?????int?j?=?1/0;??});});?}}新建一個只有一個線程的線程池,每隔0.1s提交一個任務(wù),任務(wù)中是一個1/0的計算。Exception?in?thread?"customThread?0"?java.lang.ArithmeticException:?/?by?zero?at?thread.ThreadExecutor.lambda$null$0(ThreadExecutor.java:25)?at?java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)?at?java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)?at?java.lang.Thread.run(Thread.java:748)Exception?in?thread?"customThread?1"?java.lang.ArithmeticException:?/?by?zero?at?thread.ThreadExecutor.lambda$null$0(ThreadExecutor.java:25)?at?java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)?at?java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)?at?java.lang.Thread.run(Thread.java:748)Exception?in?thread?"customThread?2"?java.lang.ArithmeticException:?/?by?zero?at?thread.ThreadExecutor.lambda$null$0(ThreadExecutor.java:25)?at?java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)?at?java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)?at?java.lang.Thread.run(Thread.java:748)Exception?in?thread?"customThread?3"?java.lang.ArithmeticException:?/?by?zero?at?thread.ThreadExecutor.lambda$null$0(ThreadExecutor.java:25)?at?java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)?at?java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)?at?java.lang.Thread.run(Thread.java:748)Exception?in?thread?"customThread?4"?java.lang.ArithmeticException:?/?by?zero?at?thread.ThreadExecutor.lambda$null$0(ThreadExecutor.java:25)?at?java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)?at?java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)?at?java.lang.Thread.run(Thread.java:748)Exception?in?thread?"customThread?5"?java.lang.ArithmeticException:?/?by?zero?at?thread.ThreadExecutor.lambda$null$0(ThreadExecutor.java:25)?at?java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)?at?java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)?at?java.lang.Thread.run(Thread.java:748)可見每次執(zhí)行的線程都不一樣,之前的線程都沒有復(fù)用。原因是因為出現(xiàn)了未捕獲的異常。我們把異常捕獲試試:public?class?ThreadExecutor?{?private?ThreadPoolExecutor?threadPoolExecutor?=?new?ThreadPoolExecutor(1,?1,?60,?TimeUnit.SECONDS,???new?ArrayBlockingQueue<>(200),?new?ThreadFactoryBuilder().setNameFormat("customThread?%d").build());?@Test?public?void?test()?{??IntStream.rangeClosed(1,?5).forEach(i?->?{???try?{????Thread.sleep(100);???}?catch?(InterruptedException?e)?{????e.printStackTrace();???}???threadPoolExecutor.execute(()?->?{????try?{?????int?j?=?1?/?0;????}?catch?(Exception?e)?{?????System.out.println(Thread.currentThread().getName()?+"?"+?e.getMessage());????}???});??});?}}customThread?0?/?by?zerocustomThread?0?/?by?zerocustomThread?0?/?by?zerocustomThread?0?/?by?zerocustomThread?0?/?by?zero可見當(dāng)異常捕獲了,線程就可以復(fù)用了。" data-itemshowtype="0" tab="innerlink" data-linktype="2" data-darkmode-color-16340410061459="rgb(156, 156, 156)" data-darkmode-original-color-16340410061459="#fff|rgb(63, 63, 63)|rgb(74, 74, 74)" wah-hotarea="click" hasload="1" style="outline: 0px; color: rgb(125, 144, 169); cursor: pointer; max-width: 100%; box-sizing: border-box !important; word-wrap: break-word !important;">我們把異常捕獲試試:

          ?{???try?{????Thread.sleep(100);???}?catch?(InterruptedException?e)?{????e.printStackTrace();???}???threadPoolExecutor.execute(()?->?{?????int?j?=?1/0;??});});?}}新建一個只有一個線程的線程池,每隔0.1s提交一個任務(wù),任務(wù)中是一個1/0的計算。Exception?in?thread?"customThread?0"?java.lang.ArithmeticException:?/?by?zero?at?thread.ThreadExecutor.lambda$null$0(ThreadExecutor.java:25)?at?java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)?at?java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)?at?java.lang.Thread.run(Thread.java:748)Exception?in?thread?"customThread?1"?java.lang.ArithmeticException:?/?by?zero?at?thread.ThreadExecutor.lambda$null$0(ThreadExecutor.java:25)?at?java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)?at?java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)?at?java.lang.Thread.run(Thread.java:748)Exception?in?thread?"customThread?2"?java.lang.ArithmeticException:?/?by?zero?at?thread.ThreadExecutor.lambda$null$0(ThreadExecutor.java:25)?at?java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)?at?java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)?at?java.lang.Thread.run(Thread.java:748)Exception?in?thread?"customThread?3"?java.lang.ArithmeticException:?/?by?zero?at?thread.ThreadExecutor.lambda$null$0(ThreadExecutor.java:25)?at?java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)?at?java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)?at?java.lang.Thread.run(Thread.java:748)Exception?in?thread?"customThread?4"?java.lang.ArithmeticException:?/?by?zero?at?thread.ThreadExecutor.lambda$null$0(ThreadExecutor.java:25)?at?java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)?at?java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)?at?java.lang.Thread.run(Thread.java:748)Exception?in?thread?"customThread?5"?java.lang.ArithmeticException:?/?by?zero?at?thread.ThreadExecutor.lambda$null$0(ThreadExecutor.java:25)?at?java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)?at?java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)?at?java.lang.Thread.run(Thread.java:748)可見每次執(zhí)行的線程都不一樣,之前的線程都沒有復(fù)用。原因是因為出現(xiàn)了未捕獲的異常。我們把異常捕獲試試:public?class?ThreadExecutor?{?private?ThreadPoolExecutor?threadPoolExecutor?=?new?ThreadPoolExecutor(1,?1,?60,?TimeUnit.SECONDS,???new?ArrayBlockingQueue<>(200),?new?ThreadFactoryBuilder().setNameFormat("customThread?%d").build());?@Test?public?void?test()?{??IntStream.rangeClosed(1,?5).forEach(i?->?{???try?{????Thread.sleep(100);???}?catch?(InterruptedException?e)?{????e.printStackTrace();???}???threadPoolExecutor.execute(()?->?{????try?{?????int?j?=?1?/?0;????}?catch?(Exception?e)?{?????System.out.println(Thread.currentThread().getName()?+"?"+?e.getMessage());????}???});??});?}}customThread?0?/?by?zerocustomThread?0?/?by?zerocustomThread?0?/?by?zerocustomThread?0?/?by?zerocustomThread?0?/?by?zero可見當(dāng)異常捕獲了,線程就可以復(fù)用了。" data-itemshowtype="0" tab="innerlink" data-linktype="2" data-darkmode-color-16340410061459="rgb(163, 163, 163)" data-darkmode-original-color-16340410061459="#fff|rgb(63, 63, 63)" wah-hotarea="click" hasload="1" style="outline: 0px; color: rgb(125, 144, 169); cursor: pointer; max-width: 100%; box-sizing: border-box !important; word-wrap: break-word !important;">public?class?ThreadExecutor?{

          ?private?ThreadPoolExecutor?threadPoolExecutor?=?new?ThreadPoolExecutor(1,?1,?60,?TimeUnit.SECONDS,
          ???new?ArrayBlockingQueue<>(200),?new?ThreadFactoryBuilder().setNameFormat("customThread?%d").build());

          ?@Test
          ?public?void?test()?{
          ??IntStream.rangeClosed(1,?5).forEach(i?->?{
          ???try?{
          ????Thread.sleep(100);
          ???}?catch?(InterruptedException?e)?{
          ????e.printStackTrace();
          ???}
          ???threadPoolExecutor.execute(()?->?{
          ????try?{
          ?????int?j?=?1?/?0;
          ????}?catch?(Exception?e)?{
          ?????System.out.println(Thread.currentThread().getName()?+"?"+?e.getMessage());
          ????}
          ???});
          ??});
          ?}
          }
          ?{???try?{????Thread.sleep(100);???}?catch?(InterruptedException?e)?{????e.printStackTrace();???}???threadPoolExecutor.execute(()?->?{?????int?j?=?1/0;??});});?}}新建一個只有一個線程的線程池,每隔0.1s提交一個任務(wù),任務(wù)中是一個1/0的計算。Exception?in?thread?"customThread?0"?java.lang.ArithmeticException:?/?by?zero?at?thread.ThreadExecutor.lambda$null$0(ThreadExecutor.java:25)?at?java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)?at?java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)?at?java.lang.Thread.run(Thread.java:748)Exception?in?thread?"customThread?1"?java.lang.ArithmeticException:?/?by?zero?at?thread.ThreadExecutor.lambda$null$0(ThreadExecutor.java:25)?at?java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)?at?java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)?at?java.lang.Thread.run(Thread.java:748)Exception?in?thread?"customThread?2"?java.lang.ArithmeticException:?/?by?zero?at?thread.ThreadExecutor.lambda$null$0(ThreadExecutor.java:25)?at?java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)?at?java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)?at?java.lang.Thread.run(Thread.java:748)Exception?in?thread?"customThread?3"?java.lang.ArithmeticException:?/?by?zero?at?thread.ThreadExecutor.lambda$null$0(ThreadExecutor.java:25)?at?java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)?at?java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)?at?java.lang.Thread.run(Thread.java:748)Exception?in?thread?"customThread?4"?java.lang.ArithmeticException:?/?by?zero?at?thread.ThreadExecutor.lambda$null$0(ThreadExecutor.java:25)?at?java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)?at?java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)?at?java.lang.Thread.run(Thread.java:748)Exception?in?thread?"customThread?5"?java.lang.ArithmeticException:?/?by?zero?at?thread.ThreadExecutor.lambda$null$0(ThreadExecutor.java:25)?at?java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)?at?java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)?at?java.lang.Thread.run(Thread.java:748)可見每次執(zhí)行的線程都不一樣,之前的線程都沒有復(fù)用。原因是因為出現(xiàn)了未捕獲的異常。我們把異常捕獲試試:public?class?ThreadExecutor?{?private?ThreadPoolExecutor?threadPoolExecutor?=?new?ThreadPoolExecutor(1,?1,?60,?TimeUnit.SECONDS,???new?ArrayBlockingQueue<>(200),?new?ThreadFactoryBuilder().setNameFormat("customThread?%d").build());?@Test?public?void?test()?{??IntStream.rangeClosed(1,?5).forEach(i?->?{???try?{????Thread.sleep(100);???}?catch?(InterruptedException?e)?{????e.printStackTrace();???}???threadPoolExecutor.execute(()?->?{????try?{?????int?j?=?1?/?0;????}?catch?(Exception?e)?{?????System.out.println(Thread.currentThread().getName()?+"?"+?e.getMessage());????}???});??});?}}customThread?0?/?by?zerocustomThread?0?/?by?zerocustomThread?0?/?by?zerocustomThread?0?/?by?zerocustomThread?0?/?by?zero可見當(dāng)異常捕獲了,線程就可以復(fù)用了。" data-itemshowtype="0" tab="innerlink" data-linktype="2" data-darkmode-color-16340410061459="rgb(163, 163, 163)" data-darkmode-original-color-16340410061459="#fff|rgb(63, 63, 63)" wah-hotarea="click" hasload="1" style="outline: 0px; color: rgb(125, 144, 169); cursor: pointer; max-width: 100%; box-sizing: border-box !important; word-wrap: break-word !important;">customThread?0?/?by?zero
          customThread?0?/?by?zero
          customThread?0?/?by?zero
          customThread?0?/?by?zero
          customThread?0?/?by?zero

          ?{???try?{????Thread.sleep(100);???}?catch?(InterruptedException?e)?{????e.printStackTrace();???}???threadPoolExecutor.execute(()?->?{?????int?j?=?1/0;??});});?}}新建一個只有一個線程的線程池,每隔0.1s提交一個任務(wù),任務(wù)中是一個1/0的計算。Exception?in?thread?"customThread?0"?java.lang.ArithmeticException:?/?by?zero?at?thread.ThreadExecutor.lambda$null$0(ThreadExecutor.java:25)?at?java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)?at?java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)?at?java.lang.Thread.run(Thread.java:748)Exception?in?thread?"customThread?1"?java.lang.ArithmeticException:?/?by?zero?at?thread.ThreadExecutor.lambda$null$0(ThreadExecutor.java:25)?at?java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)?at?java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)?at?java.lang.Thread.run(Thread.java:748)Exception?in?thread?"customThread?2"?java.lang.ArithmeticException:?/?by?zero?at?thread.ThreadExecutor.lambda$null$0(ThreadExecutor.java:25)?at?java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)?at?java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)?at?java.lang.Thread.run(Thread.java:748)Exception?in?thread?"customThread?3"?java.lang.ArithmeticException:?/?by?zero?at?thread.ThreadExecutor.lambda$null$0(ThreadExecutor.java:25)?at?java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)?at?java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)?at?java.lang.Thread.run(Thread.java:748)Exception?in?thread?"customThread?4"?java.lang.ArithmeticException:?/?by?zero?at?thread.ThreadExecutor.lambda$null$0(ThreadExecutor.java:25)?at?java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)?at?java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)?at?java.lang.Thread.run(Thread.java:748)Exception?in?thread?"customThread?5"?java.lang.ArithmeticException:?/?by?zero?at?thread.ThreadExecutor.lambda$null$0(ThreadExecutor.java:25)?at?java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)?at?java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)?at?java.lang.Thread.run(Thread.java:748)可見每次執(zhí)行的線程都不一樣,之前的線程都沒有復(fù)用。原因是因為出現(xiàn)了未捕獲的異常。我們把異常捕獲試試:public?class?ThreadExecutor?{?private?ThreadPoolExecutor?threadPoolExecutor?=?new?ThreadPoolExecutor(1,?1,?60,?TimeUnit.SECONDS,???new?ArrayBlockingQueue<>(200),?new?ThreadFactoryBuilder().setNameFormat("customThread?%d").build());?@Test?public?void?test()?{??IntStream.rangeClosed(1,?5).forEach(i?->?{???try?{????Thread.sleep(100);???}?catch?(InterruptedException?e)?{????e.printStackTrace();???}???threadPoolExecutor.execute(()?->?{????try?{?????int?j?=?1?/?0;????}?catch?(Exception?e)?{?????System.out.println(Thread.currentThread().getName()?+"?"+?e.getMessage());????}???});??});?}}customThread?0?/?by?zerocustomThread?0?/?by?zerocustomThread?0?/?by?zerocustomThread?0?/?by?zerocustomThread?0?/?by?zero可見當(dāng)異常捕獲了,線程就可以復(fù)用了。" data-itemshowtype="0" tab="innerlink" data-linktype="2" data-darkmode-color-16340410061459="rgb(163, 163, 163)" data-darkmode-original-color-16340410061459="#fff|rgb(63, 63, 63)|rgb(74, 74, 74)|rgb(58, 58, 58)" data-style="color: rgb(58, 58, 58);" class="js_darkmode__23" wah-hotarea="click" hasload="1" style="outline: 0px; color: rgb(58, 58, 58); cursor: pointer; max-width: 100%; box-sizing: border-box !important; word-wrap: break-word !important;">可見當(dāng)異常捕獲了,線程就可以復(fù)用了。另外, 多線程系列面試題和答案全部整理好了,微信搜索Java技術(shù)棧,在后臺發(fā)送:面試,可以在線閱讀。

          問題來了,我們的代碼中異常不可能全部捕獲

          如果要捕獲那些沒被業(yè)務(wù)代碼捕獲的異常,可以設(shè)置Thread類的uncaughtExceptionHandler屬性。這時使用ThreadFactoryBuilder會比較方便,ThreadFactoryBuilder是guava提供的ThreadFactory生成器。

          new?ThreadFactoryBuilder()
          .setNameFormat("customThread?%d")
          .setUncaughtExceptionHandler((t,?e)?->?System.out.println(t.getName()?+?"發(fā)生異常"?+?e.getCause()))
          .build()

          修改之后:

          public?class?ThreadExecutor?{

          ?private?static?ThreadPoolExecutor?threadPoolExecutor?=?new?ThreadPoolExecutor(1,?1,?60,?TimeUnit.SECONDS,
          ???new?ArrayBlockingQueue<>(200),
          ???new?ThreadFactoryBuilder()
          ?????.setNameFormat("customThread?%d")
          ?????.setUncaughtExceptionHandler((t,?e)?->?System.out.println("UncaughtExceptionHandler捕獲到:"?+?t.getName()?+?"發(fā)生異常"?+?e.getMessage()))
          ?????.build());

          ?@Test
          ?public?void?test()?{
          ??IntStream.rangeClosed(1,?5).forEach(i?->?{
          ???try?{
          ????Thread.sleep(100);
          ???}?catch?(InterruptedException?e)?{
          ????e.printStackTrace();
          ???}

          ???threadPoolExecutor.execute(()?->?{
          ????System.out.println("線程"?+?Thread.currentThread().getName()?+?"執(zhí)行");
          ????int?j?=?1?/?0;
          ???});
          ??});
          ?}
          }
          線程customThread?0執(zhí)行
          UncaughtExceptionHandler捕獲到:customThread 0發(fā)生異常/ by zero
          線程customThread?1執(zhí)行
          UncaughtExceptionHandler捕獲到:customThread 1發(fā)生異常/ by zero
          線程customThread?2執(zhí)行
          UncaughtExceptionHandler捕獲到:customThread 2發(fā)生異常/ by zero
          線程customThread?3執(zhí)行
          UncaughtExceptionHandler捕獲到:customThread 3發(fā)生異常/ by zero
          線程customThread?4執(zhí)行
          UncaughtExceptionHandler捕獲到:customThread 4發(fā)生異常/ by zero

          可見,結(jié)果并不是我們想象的那樣,線程池中原有的線程沒有復(fù)用!所以通過UncaughtExceptionHandler想將異常吞掉使線程復(fù)用這招貌似行不通。它只是做了一層異常的保底處理。

          推薦一個 Spring Boot 基礎(chǔ)教程及實戰(zhàn)示例:https://www.javastack.cn/categories/Spring-Boot/

          將excute改成submit試試

          public?class?ThreadExecutor?{

          ?private?static?ThreadPoolExecutor?threadPoolExecutor?=?new?ThreadPoolExecutor(1,?1,?60,?TimeUnit.SECONDS,
          ???new?ArrayBlockingQueue<>(200),
          ???new?ThreadFactoryBuilder()
          ?????.setNameFormat("customThread?%d")
          ?????.setUncaughtExceptionHandler((t,?e)?->?System.out.println("UncaughtExceptionHandler捕獲到:"?+?t.getName()?+?"發(fā)生異常"?+?e.getMessage()))
          ?????.build());

          ?@Test
          ?public?void?test()?{
          ??IntStream.rangeClosed(1,?5).forEach(i?->?{
          ???try?{
          ????Thread.sleep(100);
          ???}?catch?(InterruptedException?e)?{
          ????e.printStackTrace();
          ???}

          ???Future?future?=?threadPoolExecutor.submit(()?->?{
          ????System.out.println("線程"?+?Thread.currentThread().getName()?+?"執(zhí)行");
          ????int?j?=?1?/?0;
          ???});
          ???try?{
          ????future.get();
          ???}?catch?(InterruptedException?e)?{
          ????e.printStackTrace();
          ???}?catch?(ExecutionException?e)?{
          ????e.printStackTrace();
          ???}
          ??});
          ?}
          }
          線程customThread?0執(zhí)行
          java.util.concurrent.ExecutionException:?java.lang.ArithmeticException:?/?by?zero
          線程customThread?0執(zhí)行
          java.util.concurrent.ExecutionException:?java.lang.ArithmeticException:?/?by?zero
          線程customThread?0執(zhí)行
          java.util.concurrent.ExecutionException:?java.lang.ArithmeticException:?/?by?zero
          線程customThread?0執(zhí)行
          java.util.concurrent.ExecutionException:?java.lang.ArithmeticException:?/?by?zero
          線程customThread?0執(zhí)行
          java.util.concurrent.ExecutionException:?java.lang.ArithmeticException:?/?by?zero

          通過submit提交線程可以屏蔽線程中產(chǎn)生的異常,達(dá)到線程復(fù)用。當(dāng)get()執(zhí)行結(jié)果時異常才會拋出。

          原因是通過submit提交的線程,當(dāng)發(fā)生異常時,會將異常保存,待future.get();時才會拋出。最新面試題整理好了,點(diǎn)擊Java面試庫小程序在線刷題。

          這是Futuretask的部分run()方法,看setException:

          public?void?run()?{
          ????try?{
          ????????Callable?c?=?callable;
          ????????if?(c?!=?null?&&?state?==?NEW)?{
          ????????????V?result;
          ????????????boolean?ran;
          ????????????try?{
          ????????????????result?=?c.call();
          ????????????????ran?=?true;
          ????????????}?catch?(Throwable?ex)?{
          ????????????????result?=?null;
          ????????????????ran?=?false;
          ????????????????setException(ex);
          ????????????}
          ????????????if?(ran)
          ????????????????set(result);
          ????????}
          ????}?
          }

          protected?void?setException(Throwable?t)?{
          ????if?(UNSAFE.compareAndSwapInt(this,?stateOffset,?NEW,?COMPLETING))?{
          ????????outcome?=?t;
          ????????UNSAFE.putOrderedInt(this,?stateOffset,?EXCEPTIONAL);?//?final?state
          ????????finishCompletion();
          ????}
          }

          將異常存在outcome對象中,沒有拋出,再看get方法:

          public?V?get()?throws?InterruptedException,?ExecutionException?{
          ????int?s?=?state;
          ????if?(s?<=?COMPLETING)
          ????????s?=?awaitDone(false,?0L);
          ????return?report(s);
          }
          private?V?report(int?s)?throws?ExecutionException?{
          ????Object?x?=?outcome;
          ????if?(s?==?NORMAL)
          ????????return?(V)x;
          ????if?(s?>=?CANCELLED)
          ????????throw?new?CancellationException();
          ????throw?new?ExecutionException((Throwable)x);
          }

          當(dāng)outcome是異常時才拋出。

          總結(jié)

          1、線程池中線程中異常盡量手動捕獲

          2、通過設(shè)置ThreadFactory的UncaughtExceptionHandler可以對未捕獲的異常做保底處理,通過execute提交任務(wù),線程依然會中斷,而通過submit提交任務(wù),可以獲取線程執(zhí)行結(jié)果,線程異常會在get執(zhí)行結(jié)果時拋出。

          本文鏈接:https://blog.csdn.net/weixin_37968613/article/details/108407774

          ——————END——————

          歡迎關(guān)注“Java引導(dǎo)者”,我們分享最有價值的Java的干貨文章,助力您成為有思想的Java開發(fā)工程師!

          瀏覽 51
          點(diǎn)贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點(diǎn)贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  国产精品宾馆在线精品酒店 | 欧美视频一区二区三区四区 | 啪啪免费网址 | 欧洲成人性爱视频 | 9久视频 av夜夜 |