24.使用Java的线程池(ExecutorService)执行一组任务。
在Java中,ExecutorService是一个用于管理和控制线程的工具,它允许你提交任务给线程池来异步执行。下面是一个使用ExecutorService来执行一组任务的简单示例:
java复制代码
| import java.util.concurrent.ExecutorService;  | |
| import java.util.concurrent.Executors;  | |
| import java.util.concurrent.TimeUnit;  | |
| public class ThreadPoolExample {  | |
| public static void main(String[] args) {  | |
| // 创建一个固定大小的线程池  | |
| ExecutorService executorService = Executors.newFixedThreadPool(5);  | |
| // 提交多个任务给线程池执行  | |
| for (int i = 0; i < 10; i++) {  | |
| final int taskId = i;  | |
| executorService.submit(() -> {  | |
| System.out.println("Task " + taskId + " is running on thread " + Thread.currentThread().getName());  | |
| // 模拟任务执行耗时  | |
| try {  | |
| TimeUnit.MILLISECONDS.sleep(500);  | |
| } catch (InterruptedException e) {  | |
| e.printStackTrace();  | |
| }  | |
| System.out.println("Task " + taskId + " completed.");  | |
| });  | |
| }  | |
| // 关闭线程池,不再接受新任务,等待所有任务完成  | |
| executorService.shutdown();  | |
| try {  | |
| // 等待所有任务完成,或者超时后退出  | |
| if (!executorService.awaitTermination(60, TimeUnit.SECONDS)) {  | |
| // 如果超时,可以取消所有未完成的任务  | |
| executorService.shutdownNow();  | |
| }  | |
| } catch (InterruptedException e) {  | |
| // 如果等待过程中线程被中断,也取消所有未完成的任务  | |
| executorService.shutdownNow();  | |
| }  | |
| }  | |
| } | 
在这个例子中,我们首先使用Executors.newFixedThreadPool(5)创建了一个固定大小为5的线程池。然后,我们循环提交了10个任务给线程池执行。每个任务都是一个Runnable的匿名内部类实例,它重写了run方法以定义任务的具体执行逻辑。
在任务中,我们打印了当前任务的ID和正在执行该任务的线程名称,然后模拟了任务执行耗时(通过TimeUnit.MILLISECONDS.sleep(500)让当前线程睡眠500毫秒)。任务完成后,我们再打印一条任务完成的消息。
最后,我们调用executorService.shutdown()来关闭线程池,它表示线程池不再接受新的任务,但是会等待所有已提交的任务执行完成。然后,我们使用awaitTermination方法来等待所有任务完成,或者等待指定的超时时间后退出。如果在等待过程中线程被中断,或者在超时后仍有未完成的任务,我们调用shutdownNow()来尝试取消所有未完成的任务。
请注意,shutdownNow()方法会尝试停止所有正在执行的任务,但并不能保证所有任务都能被成功停止。它返回一个列表,包含那些未被成功停止的任务。在实际应用中,你可能需要根据具体需求来处理这些未被停止的任务。