Location>code7788 >text

Interviewer: does the thread pool crash when it encounters an unhandled exception?

Popularity:269 ℃/2024-09-19 11:41:09

First of all, this question examines your understanding of the thread pool execute method and submit method, in the use of Java thread pool, we can execute method or submit method to add tasks to the thread pool, but if the program in the thread pool in the execution of the encountered unhandled exceptions how? The next step is to look at it together.

methodologies

The execute method is used to submit a task to the thread pool for execution without a return value, it takes a parameter of type Runnable and does not return any result.

The sample code for its use is as follows:

import ;
import ;

public class ExecuteDemo {
    public static void main(String[] args) {
        ExecutorService executor = (5);
        
        // utilization execute Methodology for the submission of mandates
        (new Runnable() {
            @Override
            public void run() {
                ("Task running in " + ().getName());
                try {
                    // Simulation of mission execution
                    (2000);
                } catch (InterruptedException e) {
                    ().interrupt();
                    ("Task was interrupted");
                }
                ("Task finished");
            }
        });

        // Closing the thread pool
        ();
    }
}

methodologies

The submit method is used to submit a task that needs a return value (Callable object), or a task that doesn't need a return value but wants to get the status of the task (Runnable object, but returns a Future object).

It takes a Callable or Runnable type parameter and returns a Future object through which you can get the execution result of the task or check the status of the task.

2.1 Submission of Callable tasks

The sample code is as follows:

import ;
import ;
import ;
import ;
import ;
  
public class SubmitCallableDemo {
    public static void main(String[] args) {
        // Create a fixed-size thread pool
        ExecutorService executorService = (2);
  
        // Submit a Callable Tasks to the thread pool for execution
        Future<String> future = (new Callable<String>() {
            @Override
            public String call() throws Exception {
                (2000); // Simulation of task execution time
                return "Task's execution result";
            }  
        });
  
        try {
            // Getting the results of a task's execution
            String result = ();
            ("Task result: " + result);
        } catch (InterruptedException | ExecutionException e) {
            ();
        }  
  
        // Closing the thread pool
        ();
    }  
}

2.2 Submitting Runnable Tasks

Submit the Runnable task and get the Future object, the sample code is as follows:

import ;
import ;
import ;

public class SubmitRunnableDemo {
    public static void main(String[] args) {
        // Create a fixed-size thread pool
        ExecutorService executorService = (2);

        // Submit a Runnable task to the pool and get a Future object.
        Future<? > future = (new Runnable() {
            @Override
            public void run() {
                ("Task is running in thread: " + ().getName());
            }
        });

        // Check if the task is complete (this is just for the sake of the example, and may not be necessary in actual use)
        if (()) {
            ("Task is done"); } else {
        } else {
            ("Task is not done yet"); } else {
        }

        // Close the thread pool
        (); } else { ("Task is not done yet"); } // Close the thread pool.
    }
}

3. Encountering unhandled exceptions

The execution behavior of the thread pool when it encounters an unhandled exception is related to the method used to add the task, theThat is, the execution behavior of the execute method is different from that of the submit method when it encounters an unhandled exception.

3.1 Execute method encounters unhandled exception

The sample code is as follows:

import .*;

public class ThreadPoolExecutorExceptionTest {
    public static void main(String[] args) {
        ThreadPoolExecutor executor = new ThreadPoolExecutor(
                1,
                1,
                1000,
                ,
                new ArrayBlockingQueue<Runnable>(100));
        // Add task I
        (() -> {
            String tName = ().getName();
            ("thread name:" + tName);
            throw new RuntimeException("throw an exception");
        });
        // Add task II
        (() -> {
            String tName = ().getName();
            ("thread name:" + tName);
            throw new RuntimeException("throw an exception");
        });
    }
}

The results of the execution of the above program are as follows:

From the above results, it can be seen that the threads executing the task are different by the time an unhandled exception is encountered when the core and maximum number of threads in the thread pool are both 1, which shows:When using the execute method, if an unhandled exception is encountered, the uncaught exception is thrown and the current thread is destroyed.

3.2 Submit method encounters unhandled exception

However, when we replace the thread pool's add task method with submit(), the result is completely different, as shown in the following example code:

import .*;

public class ThreadPoolExecutorExceptionTest {
    public static void main(String[] args) {
        ThreadPoolExecutor executor = new ThreadPoolExecutor(
                1,
                1,
                1000,
                ,
                new ArrayBlockingQueue<Runnable>(100));
        // Add task I
       Future<?> future = (() -> {
            String tName = ().getName();
            ("thread name:" + tName);
            throw new RuntimeException("throw an exception");
        });
        // Add task II
        Future<?> future2 =(() -> {
            String tName = ().getName();
            ("thread name:" + tName);
            throw new RuntimeException("throw an exception");
        });
        try {
            ();
        } catch (Exception e) {
            ("run into an anomaly:"+());
        }
        try {
            ();
        } catch (Exception e) {
            ("run into an anomaly:"+());
        }
    }
}

The results of the execution of the above program are as follows:

As you can see from the above results, the submit method encounters an unhandled exception andEncapsulate the exception in the get method of the Future without directly affecting the thread that executes the task, so that the thread can continue to reuse it

wrap-up

The thread pool's execution behavior is different for different methods that add tasks when it encounters an unhandled exception:

  • execute method: When an unhandled exception is encountered, the thread crashes and an exception message is printed.
  • submit method: When an unhandled exception is encountered, the thread itself is not affected (threads can be reused), the exception information is simply encapsulated in the returned object Future.

Post-lesson Reflections

Why does the thread in the execute method crash when it encounters an unhandled exception, but the thread in the submit method is reusable?

This article has been included in my interview mini-site, which contains modules such as Redis, JVM, Concurrency, Concurrency, MySQL, Spring, Spring MVC, Spring Boot, Spring Cloud, MyBatis, Design Patterns, Message Queuing and more.