目录
1. newFixedThreadPool(int nThreads):创建一个固定大小的线程池。该线程池中的线程数量是固定的,不会随着任务的多少而改变。
2. newCachedThreadPool():创建一个缓存线程池。该线程池会根据任务的多少动态地调整线程的数量。如果有空闲线程可用,就会重用现有线程,否则会创建新的线程。
3. newSingleThreadExecutor():创建一个单线程的线程池。该线程池中只有一个线程,用于顺序执行任务。
4. newScheduledThreadPool(int corePoolSize):创建一个定时执行任务的线程池。该线程池可以按照一定的时间间隔或固定延迟周期性地执行任务。
5. newWorkStealingPool(int parallelism):创建一个工作窃取线程池。该线程池使用基于工作窃取算法的调度策略,提供优秀的并行性能。
前言
此篇文章属于Java语言必学基础内容
提示:以下是本篇文章正文内容,下面案例可供参考
一、什么是线程池?
线程池是一种用于管理和重用线程的技术。在计算机编程中,线程池是一组已经创建并准备好执行的线程。它们被组织在一个池中,以便在需要时,可以从池中获取一个线程来执行任务,而不是每次都创建一个新的线程。
线程池的优点在于可以减少频繁创建和销毁线程的开销,提高线程的重用率和执行效率。通过使用线程池,可以控制并发线程的数量,从而避免由于大量线程同时执行而导致的资源过度消耗和性能下降的问题。
线程池还可以提供一些额外的功能,例如任务调度、优先级管理和线程状态监控等。它可以在多种应用场景中使用,特别是在需要同时处理大量短时间任务的系统中,如Web服务器、数据库连接池和并发编程等。通过合理地配置线程数目和其他参数,可以更好地管理系统资源,并提高系统的稳定性和响应能力。
二、实际项目中哪些地方使用到线程池
1. 实际开发中,禁止自己new线程。
2. 使用线程池管理,异步发短信,发消息。
三、线程池的作用
核心机制:复用机制
线程池具有以下几个主要的作用:
1. 提高性能和效率:线程池可以避免频繁创建和销毁线程的开销,通过重用线程来执行任务,减少了线程创建和销毁的时间和系统资源消耗。这样可以更高效地利用系统资源,提高程序的性能和执行效率。
2. 提供限制和管理并发:线程池可以限制并发线程的数量,避免过于频繁地创建线程导致资源不足和性能下降。通过配置线程池的最大线程数目,可以控制系统的并发度,平衡资源的利用和系统的响应能力。
3. 调度和管理任务:线程池可以提供任务调度的机制,将任务按照一定的策略和优先级分配给线程执行。它可以对任务进行排队、保存、管理和监控,确保任务的有序执行,避免任务的争抢和冲突,提高系统的稳定性和可靠性。
4. 控制资源消耗:线程池可以通过控制线程数目和任务队列的大小来限制系统资源的消耗。它可以根据系统负载和资源情况动态地调整线程的数目,保证系统资源的合理分配和使用,避免资源的浪费和不均衡。
总之,线程池可以提供高效的线程管理和调度机制,优化系统的资源利用和任务执行,保证系统的响应能力和稳定性。它在并发编程和多线程应用程序中扮演着重要的角色。
四、线程池创建方式有哪些
在Java中,可以使用 `java.util.concurrent.Executors` 类提供的静态方法来创建不同类型的线程池。以下是几种常见的线程池创建方式:
1. newFixedThreadPool(int nThreads):创建一个固定大小的线程池。该线程池中的线程数量是固定的,不会随着任务的多少而改变。
2. newCachedThreadPool():创建一个缓存线程池。该线程池会根据任务的多少动态地调整线程的数量。如果有空闲线程可用,就会重用现有线程,否则会创建新的线程。
3. newSingleThreadExecutor():创建一个单线程的线程池。该线程池中只有一个线程,用于顺序执行任务。
4. newScheduledThreadPool(int corePoolSize):创建一个定时执行任务的线程池。该线程池可以按照一定的时间间隔或固定延迟周期性地执行任务。
5. newWorkStealingPool(int parallelism):创建一个工作窃取线程池。该线程池使用基于工作窃取算法的调度策略,提供优秀的并行性能。
这些方法返回的都是 ExecutorService接口的实例,可以使用该接口来提交任务,并对线程池进行管理和控制。通过设置线程池参数,如线程数、任务队列、拒绝策略等,可以根据具体的需求来创建适当的线程池。
另外,如果需要更加精细地控制线程池的创建和配置,可以使用 ThreadPoolExecutor 类进行手动创建。这个类提供了更多的参数和方法来自定义线程池的行为。
五、手写线程池:
package Study_Executors;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.BlockingDeque;
import java.util.concurrent.LinkedBlockingDeque;
public class MyExecutors {
private List<workThread> threadList;
private final BlockingDeque<Runnable> runnables; //队列
private boolean isRun = true;
/**
* 1.提前创建好固定的线程一直在运行状态-----死循环实现
* 2.提交线程任务缓存到一个并发队列集合中,交给正在运行的线程执行
* 3.正在运行的线程就从队列中获取该任务进行执行
*/
public MyExecutors(int maxThreadCount,int dequeSize){
runnables = new LinkedBlockingDeque<>(dequeSize);
threadList = new ArrayList<>(maxThreadCount);
for (int i = 0; i < maxThreadCount; i++) {
new workThread().start();
}
}
public boolean execute(Runnable command){
return runnables.offer(command);
}
class workThread extends Thread{
@Override
public void run() {
while(isRun||runnables.size()>0){
Runnable runnable = runnables.poll();
if (runnable!=null){
runnable.run();
}
}
}
}
public static void main(String[] args) {
MyExecutors myExecutors = new MyExecutors(2,20);
for (int i = 0; i < 10; i++) {
int finalI = i;
myExecutors.execute(new Runnable() {
@Override
public void run() {
System.out.println(Thread.currentThread().getName()+","+ finalI);
}
});
}
myExecutors.isRun=false;
}
}
运行结果: