自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

線程池遇到未處理的異常會(huì)崩潰嗎?

開(kāi)發(fā) 前端
execute 方法用于提交一個(gè)不需要返回值的任務(wù)給線程池執(zhí)行,它接收一個(gè) Runnable 類型的參數(shù),并且不返回任何結(jié)果。

首先,這個(gè)問(wèn)題考察的是你對(duì)線程池 execute 方法和 submit 方法的理解,在 Java 線程池的使用中,我們可以通過(guò) execute 方法或 submit 方法給線程池添加任務(wù),但如果線程池中的程序在執(zhí)行時(shí),遇到了未處理的異常會(huì)怎么呢?接下來(lái)我們一起來(lái)看。

1.execute方法

execute 方法用于提交一個(gè)不需要返回值的任務(wù)給線程池執(zhí)行,它接收一個(gè) Runnable 類型的參數(shù),并且不返回任何結(jié)果。

它的使用示例代碼如下:

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class ExecuteDemo {
    public static void main(String[] args) {
        ExecutorService executor = Executors.newFixedThreadPool(5);
        
        // 使用 execute 方法提交任務(wù)
        executor.execute(new Runnable() {
            @Override
            public void run() {
                System.out.println("Task running in " + Thread.currentThread().getName());
                try {
                    // 模擬任務(wù)執(zhí)行
                    Thread.sleep(2000);
                } catch (InterruptedException e) {
                    Thread.currentThread().interrupt();
                    System.err.println("Task was interrupted");
                }
                System.out.println("Task finished");
            }
        });

        // 關(guān)閉線程池
        executor.shutdown();
    }
}

2.submit方法

submit 方法用于提交一個(gè)需要返回值的任務(wù)(Callable 對(duì)象),或者不需要返回值但希望獲取任務(wù)狀態(tài)的任務(wù)(Runnable 對(duì)象,但會(huì)返回一個(gè) Future 對(duì)象)。

它接收一個(gè) Callable 或 Runnable 類型的參數(shù),并返回一個(gè) Future 對(duì)象,通過(guò)該對(duì)象可以獲取任務(wù)的執(zhí)行結(jié)果或檢查任務(wù)的狀態(tài)。

2.1 提交Callable任務(wù)

示例代碼如下:

import java.util.concurrent.Callable;  
import java.util.concurrent.ExecutionException;  
import java.util.concurrent.ExecutorService;  
import java.util.concurrent.Executors;  
import java.util.concurrent.Future;  
  
public class SubmitCallableDemo {  
    public static void main(String[] args) {  
        // 創(chuàng)建一個(gè)固定大小的線程池  
        ExecutorService executorService = Executors.newFixedThreadPool(2);  
  
        // 提交一個(gè) Callable 任務(wù)給線程池執(zhí)行  
        Future<String> future = executorService.submit(new Callable<String>() {  
            @Override  
            public String call() throws Exception {  
                Thread.sleep(2000); // 模擬任務(wù)執(zhí)行時(shí)間  
                return "Task's execution result";  
            }  
        });  
  
        try {  
            // 獲取任務(wù)的執(zhí)行結(jié)果  
            String result = future.get();  
            System.out.println("Task result: " + result);  
        } catch (InterruptedException | ExecutionException e) {  
            e.printStackTrace();  
        }  
  
        // 關(guān)閉線程池  
        executorService.shutdown();  
    }  
}

2.2 提交Runnable任務(wù)

提交 Runnable 任務(wù)并獲取 Future 對(duì)象,示例代碼如下:

import java.util.concurrent.ExecutorService;  
import java.util.concurrent.Executors;  
import java.util.concurrent.Future;  
  
public class SubmitRunnableDemo {  
    public static void main(String[] args) {  
        // 創(chuàng)建一個(gè)固定大小的線程池  
        ExecutorService executorService = Executors.newFixedThreadPool(2);  
  
        // 提交一個(gè) Runnable 任務(wù)給線程池執(zhí)行,并獲取一個(gè) Future 對(duì)象  
        Future<?> future = executorService.submit(new Runnable() {  
            @Override  
            public void run() {  
                System.out.println("Task is running in thread: " + Thread.currentThread().getName());  
            }  
        });  
  
        // 檢查任務(wù)是否完成(這里只是為了示例,實(shí)際使用中可能不需要這樣做)  
        if (future.isDone()) {  
            System.out.println("Task is done");  
        } else {  
            System.out.println("Task is not done yet");  
        }  
  
        // 關(guān)閉線程池  
        executorService.shutdown();  
    }  
}

3.遇到未處理異常

線程池遇到未處理的異常執(zhí)行行為和添加任務(wù)的方法有關(guān),也就是說(shuō) execute 方法和 submit 方法在遇到未處理的異常時(shí)執(zhí)行行為是不一樣的。

3.1 execute方法遇到未處理異常

示例代碼如下:

import java.util.concurrent.*;

public class ThreadPoolExecutorExceptionTest {
    public static void main(String[] args)  {
        ThreadPoolExecutor executor = new ThreadPoolExecutor(
                1,
                1,
                1000,
                TimeUnit.MILLISECONDS,
                new ArrayBlockingQueue<Runnable>(100));
        // 添加任務(wù)一
        executor.execute(() -> {
            String tName = Thread.currentThread().getName();
            System.out.println("線程名:" + tName);
            throw new RuntimeException("拋出異常");
        });
        // 添加任務(wù)二
        executor.execute(() -> {
            String tName = Thread.currentThread().getName();
            System.out.println("線程名:" + tName);
            throw new RuntimeException("拋出異常");
        });
    }
}

以上程序的執(zhí)行結(jié)果如下:

圖片圖片

從上述結(jié)果可以看出,線程池中的核心和最大線程數(shù)都為 1 的情況下,到遇到未處理的異常時(shí),執(zhí)行任務(wù)的線程卻不一樣,這說(shuō)明了:當(dāng)使用 execute 方法時(shí),如果遇到未處理的異常,會(huì)拋出未捕獲的異常,并將當(dāng)前線程進(jìn)行銷毀。

3.2 submit方法遇到未處理異常

然而,當(dāng)我們將線程池的添加任務(wù)方法換成 submit() 之后,執(zhí)行結(jié)果又完全不同了,以下是示例代碼:

import java.util.concurrent.*;

public class ThreadPoolExecutorExceptionTest {
    public static void main(String[] args)  {
        ThreadPoolExecutor executor = new ThreadPoolExecutor(
                1,
                1,
                1000,
                TimeUnit.MILLISECONDS,
                new ArrayBlockingQueue<Runnable>(100));
        // 添加任務(wù)一
       Future<?> future = executor.submit(() -> {
            String tName = Thread.currentThread().getName();
            System.out.println("線程名:" + tName);
            throw new RuntimeException("拋出異常");
        });
        // 添加任務(wù)二
        Future<?> future2 =executor.submit(() -> {
            String tName = Thread.currentThread().getName();
            System.out.println("線程名:" + tName);
            throw new RuntimeException("拋出異常");
        });
        try {
            future.get();
        } catch (Exception e) {
            System.out.println("遇到異常:"+e.getMessage());
        }
        try {
            future2.get();
        } catch (Exception e) {
            System.out.println("遇到異常:"+e.getMessage());
        }
    }
}

以上程序的執(zhí)行結(jié)果如下:

圖片圖片

從上述結(jié)果可以看出,submit 方法遇到未處理的異常時(shí),并將該異常封裝在 Future 的 get 方法中,而不會(huì)直接影響執(zhí)行任務(wù)的線程,這樣線程就可以繼續(xù)復(fù)用了。

小結(jié)

線程池在遇到未處理的異常時(shí),不同添加任務(wù)的方法的執(zhí)行行為是不同的:

  • execute 方法:遇到未處理的異常,線程會(huì)崩潰,并打印異常信息。
  • submit 方法:遇到未處理的異常,線程本身不會(huì)受到影響(線程可以復(fù)用),只是將異常信息封裝到返回的對(duì)象 Future 中。
責(zé)任編輯:武曉燕 來(lái)源: 磊哥和Java
相關(guān)推薦

2009-12-25 10:01:23

WinForm程序

2023-10-12 22:35:08

2025-02-14 10:13:55

2020-07-27 13:49:47

Python編程語(yǔ)言開(kāi)發(fā)

2024-06-28 10:29:18

異常處理Python

2024-01-08 09:09:40

線程池異常黑洞Futrue

2022-03-23 07:54:05

Java線程池系統(tǒng)

2022-07-04 09:17:37

Flask開(kāi)源

2023-07-27 07:37:47

消息自定義函數(shù)

2024-07-16 08:36:33

線程池父子任務(wù)微服務(wù)

2025-02-17 00:25:00

Winform開(kāi)發(fā)

2010-04-14 09:20:26

.NET多線程

2020-12-21 06:18:15

Android線程主線程

2025-02-05 14:28:19

2024-08-29 08:54:35

2023-02-02 08:56:25

線程池線程submit

2012-05-15 02:18:31

Java線程池

2025-01-03 08:40:53

Java并發(fā)編程Guava庫(kù)

2023-06-08 07:48:03

Java線程池

2024-10-09 15:58:02

點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)