线程池是什么
线程池是一种常用的多线程处理方式,它可以有效地提高程序的效率,同时还能降低资源的消耗。下面是使用线程池的基本步骤:
1.创建线程池对象:首先需要创建一个线程池对象,定义线程池的大小、线程的优先级、线程的存活时间等属性。
2.创建任务队列:创建一个任务队列,用来存储待执行的任务。
3.创建任务:创建Runnable或Callable类型的任务。
4.提交任务:将任务提交到任务队列中。
5.执行任务:线程池中的线程会自动从任务队列中获取任务并执行,直到线程池中的所有线程都处于空闲状态。
6.关闭线程池:当任务执行完毕后需要关闭线程池,释放线程池中的资源。
使用线程池可以有效地提高程序的性能,同时也可以避免因为线程的创建和销毁带来的性能开销,是多线程编程中的常用技术。
在JAVA中主要是使用ThreadPoolExecutor类来创建线程池,并且JDK中也提供了Executors工厂类来创建线程池。
线程池的结构
- corePoolSize,核心线程数量,决定是否创建新的线程来处理到来的任务,在线程池当中无论空闲多久都不会被删除的线程
- maximumPoolSize,最大线程数量,线程池中允许创建线程地最大数量
- keepAliveTime,线程空闲时存活的时间,临时线程(线程池中出核心线程之外的线程)空闲了多久就会被淘汰的时间。
- unit,空闲存活时间单位,临时线程空闲了多久就会被淘汰的时间单位,要用枚举类TimeUnit类作为参数
- workQueue,任务队列,用于存放已提交的任务,就是创建一个阻塞队列作为参数传入,就是当线程池当中线程数量已经达到了最大线程数量,允许多少个任务排队获取线程,其余的用handler那个方案来处理。
- threadFactory,线程工厂,用于创建线程执行任务
- handler,拒绝策略,当线程池处于饱和时,使用某种策略来拒绝任务提交,当等待队列中也排满时要怎么处理这些任务。
public ThreadPoolExecutor(int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue<Runnable> workQueue,
ThreadFactory threadFactory,
RejectedExecutionHandler handler)
线程池的工作流程
手写一个简单的线程池
package sty.ThreadPool;
import java.util.ArrayList;
public class MyPool {
ArrayList<Thread> workerThreads;
ArrayList<Runnable> tasks;
public MyPool(int number){
workerThreads = new ArrayList<>();
tasks = new ArrayList<>();
WorkerThread workerThread=new WorkerThread(tasks);
for(int i=0;i<number;i++){
Thread td = new Thread(workerThread);
workerThreads.add(td);
td.start();
}
}
public void excute(Runnable task){
synchronized (tasks){
tasks.add(task);
tasks.notifyAll();
}
}
}
线程池类,用于创建线程以及提交任务
public class WorkerThread implements Runnable{
public ArrayList<Runnable> tasks;
public Runnable task;
public WorkerThread(ArrayList<Runnable> tasks){
this.tasks=tasks;
}
@Override
public void run() {
while(true) {
//判断任务队列中是否有任务,如任务全部完成则进入等待
synchronized (tasks) {
if (tasks.isEmpty()) {
try {
System.out.println("线程" + Thread.currentThread().getName() + "进入wait状态");
tasks.wait();
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
} else {
task = tasks.get(0);
System.out.println(task);
tasks.remove(0);
System.out.println("线程" + Thread.currentThread().getName() + "准备进行工作");
task.run();
}
}
}
}
}
工作线程类,用于管理run()方法,从任务队列中取出任务执行。
public class DEMO {
public static void main(String[] args) throws InterruptedException {
MyPool myPool = new MyPool(5);
for(int i = 0; i<10;i++){
myPool.excute(new MyTask(i));
}
}
static class MyTask implements Runnable{
private int id;
public MyTask(int id) {
this.id = id;
}
@Override
public void run() {
String name =Thread.currentThread().getName();
System.out.println("线程:"+name+"即将执行任务:"+id);
try {
Thread.sleep(200);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("线程:"+name+"完成任务:"+id);
}
@Override
public String toString() {
return "MyTask{" +
"id=" + id +
'}';
}
}
}
测试类,创建线程池并添加任务。