马士兵java架构师

您现在的位置是:java学习笔记 >

java学习笔记

java 线程池如何实现多线程?

2024-03-01 16:29:22java学习笔记 本文浏览次数:1 百度已收录

本 文 目 录

# <h2>Java线程池实现多线程</h2>

## 一、线程池的作用与主要运用的方法

在Java中,线程池是一种用于管理和控制多个并发线程的工具,其核心作用是减少线程创建和销毁开销、合理管理资源以及提供统一的并发执行框架。通过使用`java.util.concurrent`包下的ThreadPoolExecutor类,我们可以轻松地创建并配置一个线程池,从而高效地执行大量任务。

## 1. 创建线程池步骤:初始化配置

### 初始化线程池参数
- **核心线程数**:线程池中的常驻线程数量。
- **最大线程数**:线程池允许的最大线程数,超过这个数量的任务将排队等待。
- **线程存活时间**:非核心线程空闲时等待新任务的最长时间,超时则自动终止。
- **任务队列**:用于存放待处理任务的BlockingQueue。

```java
int corePoolSize = 5;
int maximumPoolSize = 10;
long keepAliveTime = 60L;
 TimeUnit unit = TimeUnit.SECONDS;
BlockingQueue<Runnable> workQueue = new LinkedBlockingQueue<>();
ThreadFactory threadFactory = Executors.defaultThreadFactory();
RejectedExecutionHandler handler = new ThreadPoolExecutor.AbortPolicy();
ThreadPoolExecutor executor = new ThreadPoolExecutor(corePoolSize, 
                                                    maximumPoolSize, 
                                                    keepAliveTime, 
                                                    unit, 
                                                    workQueue, 
                                                    threadFactory, 
                                                    handler);

2. 提交任务至线程池步骤:execute方法

提交任务

通过调用线程池的execute(Runnable task)方法提交任务到线程池中,由线程池根据当前线程状态选择从核心线程、非核心线程或任务队列中获取资源来执行该任务。

executor.execute(new Runnable() {
    @Override
    public void run() {
        // 这里编写具体的任务逻辑
        System.out.println("正在执行任务...");
    }
});

3. 关闭线程池步骤:shutdown方法

关闭线程池

当所有任务执行完毕或者不再需要线程池时,可以调用shutdown()shutdownNow()方法关闭线程池。前者会等待所有已提交任务完成后再停止,后者尝试取消未开始的任务并中断正在运行的任务。

executor.shutdown();
// 等待所有任务完成
while (!executor.isTerminated()) {
    Thread.sleep(100);
}
System.out.println("所有任务已完成,线程池已关闭");

四、总结与注意事项

  • 使用线程池能够有效地提高系统资源利用率,防止过多线程导致的系统资源耗尽问题。
  • 根据实际应用场景合理设置线程池参数,如CPU核心数、任务特性(IO密集型或CPU密集型)等。
  • 注意处理拒绝策略,当线程池和队列满载时,可通过自定义RejectedExecutionHandler进行特殊处理。

五、完整代码示例

import java.util.concurrent.*;

public class ThreadPoolExample {

    public static void main(String[] args) {
        int corePoolSize = 5;
        int maximumPoolSize = 10;
        long keepAliveTime = 60L;
        TimeUnit unit = TimeUnit.SECONDS;
        BlockingQueue<Runnable> workQueue = new LinkedBlockingQueue<>();
        ThreadFactory threadFactory = Executors.defaultThreadFactory();
        RejectedExecutionHandler handler = new ThreadPoolExecutor.AbortPolicy();
        ThreadPoolExecutor executor = new ThreadPoolExecutor(corePoolSize, 
                                                            maximumPoolSize, 
                                                            keepAliveTime, 
                                                            unit, 
                                                            workQueue, 
                                                            threadFactory, 
                                                            handler);

        for (int i = 0; i < 20; i++) {
            final int taskId = i;
            executor.execute(new Runnable() {
                @Override
                public void run() {
                    System.out.println("Task ID: " + taskId + " is running by " + Thread.currentThread().getName());
                    try {
                        Thread.sleep(1000); // 模拟任务执行时间
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            });
        }

        executor.shutdown();
        while (!executor.isTerminated()) {
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        System.out.println("所有任务已完成,线程池已关闭");
    }
}