更新时间:2023-04-13 来源:黑马程序员 浏览量:
Java中创建线程池时,有以下几个核心构造参数:
线程池中的核心线程数量,即在没有任务需要执行时线程池的基本大小。
线程池中允许的最大线程数量。
当线程池中的线程数量大于核心线程数量时,多余的空闲线程在等待新任务到来时能够存活的最长时间。
keepAliveTime 参数的时间单位。
用于存放待执行任务的阻塞队列。
用于创建新线程的工厂类。
当线程池中的线程数量达到最大线程数量并且队列已满时的饱和策略,常见的策略有抛出异常、丢弃任务、丢弃队列中最老的任务、直接在调用者线程中执行等。
下面是一个基本的线程池创建和使用的代码演示:
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class ThreadPoolDemo {
public static void main(String[] args) {
// 创建一个具有固定线程数的线程池
ExecutorService executor = Executors.newFixedThreadPool(2);
// 提交任务到线程池中
for (int i = 1; i <= 10; i++) {
executor.submit(new Task(i));
}
// 关闭线程池
executor.shutdown();
}
}
class Task implements Runnable {
private int taskId;
public Task(int taskId) {
this.taskId = taskId;
}
@Override
public void run() {
System.out.println("Task #" + taskId + " is running.");
}
}
这个例子中,创建了一个具有固定线程数(2个)的线程池,并提交了10个任务到线程池中执行。每个任务是一个简单的Runnable对象,只是打印了一行文本。在执行完所有任务后,线程池会自动关闭。
如果需要指定线程池的其他构造参数,可以使用ThreadPoolExecutor类来创建线程池。接下来我们用一段代码,来演示如何使用ThreadPoolExecutor类创建一个具有4个核心线程、最大线程数为8、空闲线程存活时间为30秒、任务队列大小为20的线程池。
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
public class ThreadPoolDemo {
public static void main(String[] args) {
int corePoolSize = 4;
int maximumPoolSize = 8;
long keepAliveTime = 30;
TimeUnit unit = TimeUnit.SECONDS;
ArrayBlockingQueue<Runnable> workQueue = new ArrayBlockingQueue<>(20);
ThreadPoolExecutor executor = new ThreadPoolExecutor(
corePoolSize,
maximumPoolSize,
keepAliveTime,
unit,
workQueue);
// 提交任务到线程池中
for (int i = 1; i <= 20; i++) {
executor.submit(new Task(i));
}
// 关闭线程池
executor.shutdown();
}
}
class Task implements Runnable {
private int taskId;
public Task(int taskId) {
this.taskId = taskId;
}
@Override
public void run() {
System.out.println("Task #" + taskId + " is running.");
}
}
在这个例子中,首先定义了线程池的各个构造参数,然后使用ThreadPoolExecutor类创建了一个具有指定参数的线程池。这个例子中,任务队列使用了一个ArrayBlockingQueue,它可以存储20个任务。在执行完所有任务后,线程池会自动关闭。
除了使用ThreadPoolExecutor类,还可以使用Executors类的其他静态工厂方法来创建不同类型的线程池:
1.创建一个具有单个线程的线程池,适用于需要按顺序执行任务的情况。
ExecutorService executor = Executors.newSingleThreadExecutor();
2.创建一个具有固定线程数的线程池,适用于需要保证线程数量固定的情况。
ExecutorService executor = Executors.newFixedThreadPool(4);
3.创建一个具有缓存的线程池,适用于需要执行大量短期异步任务的情况。这个线程池会根据任务的数量动态调整线程数量,如果线程池中的线程闲置时间超过60秒,这些线程就会被终止并从线程池中移除。
ExecutorService executor = Executors.newCachedThreadPool();
4.创建一个具有调度功能的线程池,适用于需要按一定间隔执行任务的情况。这个线程池会在指定的延迟后,周期性地执行任务。
ScheduledExecutorService executor = Executors.newScheduledThreadPool(2);
executor.scheduleAtFixedRate(new Task(), 0, 1, TimeUnit.SECONDS);
在这个例子中,创建了一个具有两个线程的ScheduledExecutorService,然后使用scheduleAtFixedRate方法来周期性地执行任务。这个方法的参数说明:第一个参数是要执行的任务,第二个参数是任务的初始延迟时间,第三个参数是任务的执行周期,第四个参数是时间单位。
总的来说,Java中的线程池提供了一种高效管理线程的方式,能够避免频繁创建和销毁线程,提高程序的性能和稳定性。在使用线程池时,需要根据实际情况选择不同类型的线程池和合适的构造参数。