文章目录
什么是线程
是操作系统能够进行运算调度的最小单位。(例如: cpu 对前端发往后端的一个请求的处理叫一个线程)
线程池出现背景
1 、并发请求多,处理时间长
2 、摩尔定律:处理器的性能大约每两年翻一倍(硬件成本降低)
什么是线程池
线程池是一种多线程处理形式,处理过程中将任务添加到队列,然后在创建线程后自动启动这些任务。线程池线程都是后台线程。每个线程都使用默认的堆栈大小,以默认的优先级运行,并处于多线程单元中。
使用线程池的必要性
成本降低,可以使用空间换时间
线程池参数
1 、 corePoolSize (线程池基本大小)必须大于或等于 0 ;
2 、 maximumPoolSize (线程池最大大小)必须大于或等于 1 ,必须大于或等 等于 corePoolSize ;
3 、 keepAliveTime (线程存活保持时间)必须大于或等于 0 ;
4 、 unit (存活时间的单位)
5 、 workQueue (任务队列)不能为空;
6 、 threadFactory (线程工厂)不能为空,默认为 DefaultThreadFactory 类
7 、 handler (线程饱和策略)不能为空,默认策略ThreadPoolExecutor.AbortPolicy
线程池种类
1.CachedThreadPool :适合使用在任务量大但耗时少的任务。
2.FixedThreadPool :适合使用在任务量比较固定但耗时长的任务。
3.ScheduledThreadPool :适合使用在执行定时任务和具体固定周期的重复任务。
4.SingleThreadPool :适合使用在多个任务顺序执行的场景。
5.newWorkStealingPool: 适合使用在很耗时的任务中
CachedThreadPool(可缓存线程池)
1. 简介
CachedThreadPool是Java中的一种线程池实现,它根据需要创建新线程,并且会在60秒内回收空闲线程。如果任务数量增加,会自动创建新的线程来处理任务;如果任务数量减少,空闲线程会在60秒后被回收。
2. 特点
- 动态调整:CachedThreadPool的线程数量是动态调整的,会根据任务的数量自动创建或回收线程。
- 空闲线程回收:如果线程空闲超过60秒,会被回收释放资源。
- 无界队列:CachedThreadPool使用的是无界队列,可以存放任意数量的任务。
3. 适用场景
CachedThreadPool适用于以下场景:
- 短时间任务:如果有大量的短时间任务需要处理,可以使用CachedThreadPool来动态创建线程,避免线程的频繁创建和销毁。
- 任务处理速度不一致:如果任务的处理速度不一致,有些任务可能会比较耗时,可以使用CachedThreadPool来根据任务的数量动态调整线程的数量,提高任务的处理效率。
4. 使用示例
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class CachedThreadPoolExample {
public static void main(String[] args) {
// 创建可缓存线程池
ExecutorService executor = Executors.newCachedThreadPool();
// 提交任务
for (int i = 0; i < 10; i++) {
final int taskIndex = i;
executor.execute(() -> {
System.out.println("Task " + taskIndex + " is running.");
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Task " + taskIndex + " is finished.");
});
}
// 关闭线程池
executor.shutdown();
}
}
5. 总结
CachedThreadPool是一种动态调整线程数量的线程池,适用于短时间任务和任务处理速度不一致的场景。它会根据任务的数量自动创建或回收线程,并且空闲线程会在60秒后被回收。通过合理使用CachedThreadPool,可以提高线程的利用率和程序的性能。
FixedThreadPool(固定大小线程池)
1. 简介
FixedThreadPool是Java中的一种线程池实现,它在初始化时创建指定数量的线程,并且这些线程会一直存在,不会被回收。如果所有线程都处于忙碌状态,新的任务会被放入等待队列中。
2. 特点
- 固定大小:FixedThreadPool的线程数量是固定的,不会根据任务的数量进行调整。
- 长期存在:线程在初始化时就创建好,并且会一直存在,不会被回收。
- 任务队列:如果所有线程都处于忙碌状态,新的任务会被放入等待队列中,等待有空闲线程时执行。
3. 适用场景
FixedThreadPool适用于以下场景:
- 任务数量已知:如果任务的数量是已知的,并且不会有太大的波动,可以使用FixedThreadPool来提前创建好固定数量的线程,避免线程的频繁创建和销毁。
- 资源受限:如果系统资源有限,无法支持大量的线程创建和销毁,可以使用FixedThreadPool来控制线程的数量,避免资源的浪费。
4. 使用示例
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class FixedThreadPoolExample {
public static void main(String[] args) {
// 创建固定大小为3的线程池
ExecutorService executor = Executors.newFixedThreadPool(3);
// 提交任务
for (int i = 0; i < 10; i++) {
final int taskIndex = i;
executor.execute(() -> {
System.out.println("Task " + taskIndex + " is running.");
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Task " + taskIndex + " is finished.");
});
}
// 关闭线程池
executor.shutdown();
}
}
5. 总结
FixedThreadPool是一种固定大小的线程池,适用于任务数量已知且资源受限的场景。它可以提前创建好固定数量的线程,并且这些线程会一直存在,不会被回收。如果所有线程都处于忙碌状态,新的任务会被放入等待队列中。通过合理使用FixedThreadPool,可以提高线程的利用率和程序的性能。
ScheduledThreadPool(定时线程池)
1. 简介
ScheduledThreadPool是Java中的一种线程池实现,它可以在指定的时间间隔内周期性地执行任务。它可以用于定时执行任务,或者周期性地执行任务。
2. 特点
- 定时执行:ScheduledThreadPool可以在指定的时间间隔内周期性地执行任务。
- 可控线程数量:可以通过参数来控制线程的数量,避免资源的浪费。
- 任务队列:ScheduledThreadPool使用的是有界队列,可以存放指定数量的任务。
3. 适用场景
ScheduledThreadPool适用于以下场景:
- 定时任务:如果有需要定时执行的任务,可以使用ScheduledThreadPool来执行任务。
- 周期性任务:如果有需要周期性执行的任务,可以使用ScheduledThreadPool来执行任务。
4. 使用示例
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
public class ScheduledThreadPoolExample {
public static void main(String[] args) {
// 创建定时线程池
ScheduledExecutorService executor = Executors.newScheduledThreadPool(3);
// 延迟1秒后执行任务
executor.schedule(() -> {
System.out.println("Task 1 is running.");
}, 1, TimeUnit.SECONDS);
// 延迟2秒后执行任务,然后每3秒执行一次
executor.scheduleAtFixedRate(() -> {
System.out.println("Task 2 is running.");
}, 2, 3, TimeUnit.SECONDS);
// 关闭线程池
executor.shutdown();
}
}
5. 总结
ScheduledThreadPool是一种定时执行任务的线程池,适用于定时任务和周期性任务的场景。它可以在指定的时间间隔内周期性地执行任务,并且可以通过参数来控制线程的数量。通过合理使用ScheduledThreadPool,可以实现任务的定时执行和周期性执行,提高程序的灵活性和效率。
SingleThreadPool(单线程池)
1. 简介
SingleThreadPool是Java中的一种线程池实现,它只有一个工作线程来执行任务。它可以保证任务按照顺序执行,不会并发执行。当工作线程因为异常退出时,SingleThreadPool会创建一个新的工作线程来替代。
2. 特点
- 单线程执行:SingleThreadPool只有一个工作线程来执行任务,保证任务按照顺序执行。
- 异常处理:当工作线程因为异常退出时,SingleThreadPool会创建一个新的工作线程来替代,保证任务的连续执行。
- 有界队列:SingleThreadPool使用的是有界队列,可以存放指定数量的任务。
3. 适用场景
SingleThreadPool适用于以下场景:
- 顺序执行:如果有需要按照顺序执行的任务,可以使用SingleThreadPool来执行任务。
- 异常处理:如果任务执行过程中可能会出现异常,需要保证任务的连续执行,可以使用SingleThreadPool来执行任务。
4. 使用示例
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class SingleThreadPoolExample {
public static void main(String[] args) {
// 创建单线程池
ExecutorService executor = Executors.newSingleThreadExecutor();
// 提交任务
for (int i = 0; i < 10; i++) {
final int taskIndex = i;
executor.execute(() -> {
System.out.println("Task " + taskIndex + " is running.");
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Task " + taskIndex + " is finished.");
});
}
// 关闭线程池
executor.shutdown();
}
}
5. 总结
SingleThreadPool是一种只有一个工作线程的线程池,适用于需要按照顺序执行任务和保证任务连续执行的场景。它可以保证任务按照顺序执行,当工作线程因为异常退出时,会创建一个新的工作线程来替代。通过合理使用SingleThreadPool,可以实现任务的顺序执行和异常处理,提高程序的可靠性和可维护性。
newWorkStealingPool(工作窃取线程池)
1. 简介
newWorkStealingPool是Java中的一种线程池实现,它是基于ForkJoinPool的一种扩展。工作窃取线程池使用了一种工作窃取算法,可以提高任务的执行效率。它的特点是每个线程都有自己的任务队列,当一个线程完成自己的任务后,会从其他线程的任务队列中窃取任务来执行。
2. 特点
- 并行执行:工作窃取线程池可以并行执行多个任务,提高任务的执行效率。
- 动态调整:工作窃取线程池可以根据任务的数量和线程的数量自动调整线程池的大小,提高资源的利用率。
- 工作窃取算法:工作窃取线程池使用了一种工作窃取算法,可以提高任务的执行效率。
3. 适用场景
newWorkStealingPool适用于以下场景:
- 大量独立任务:如果有大量的独立任务需要执行,并且任务之间没有依赖关系,可以使用工作窃取线程池来并行执行任务,提高执行效率。
- CPU密集型任务:如果任务是CPU密集型的,可以使用工作窃取线程池来充分利用CPU资源,提高任务的执行效率。
4. 使用示例
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class WorkStealingPoolExample {
public static void main(String[] args) {
// 创建工作窃取线程池
ExecutorService executor = Executors.newWorkStealingPool();
// 提交任务
for (int i = 0; i < 10; i++) {
final int taskIndex = i;
executor.execute(() -> {
System.out.println("Task " + taskIndex + " is running.");
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Task " + taskIndex + " is finished.");
});
}
// 关闭线程池
executor.shutdown();
}
}
5. 总结
newWorkStealingPool是一种基于ForkJoinPool的工作窃取线程池,适用于大量独立任务和CPU密集型任务的场景。它可以并行执行多个任务,提高任务的执行效率。工作窃取线程池使用了一种工作窃取算法,可以充分利用CPU资源,提高任务的执行效率。通过合理使用newWorkStealingPool,可以实现任务的并行执行和资源的高效利用,提高程序的性能和响应速度。