Java线程池与Executor框架

时间:2022-03-05 15:42:56

Java线程池:

Java线程池在Java并发中应用十分广泛。而使用线程池也会带来很多好处:1.降低资源消耗。通过重复利用已创建的线程降低线程创建和销毁的消耗;2.提高响应速度。当任务到达时,任务可以不需要等待线程创建就可以立即执行;3.提高线程的可管理性。使用线程池可以对线程进行统一分配、调优和监控。

线程池的实现原理:在线程池得到初始化之后,提交新任务到线程池。1.线程池判断核心线程池是否已全部被使用。如果不是,就调用一个的工作线程处理新任务。如果核心线程池已满,就进入下个处理操作。2.线程池判断工作队列是否已满。如果工作队列未满,将任务加入工作队列等候处理。如果工作队列也满了,就进入下一个处理操作。3.线程池判断其中的已经在工作的线程数量是否超出了最大数量。如果没有就创建一个线程执行任务。如果满了就交给饱和策略进行处理

线程池的实现:以下是用伪代码实现的一个线程池的模板。

public class MyThreadPool{
public MyThreadPool(){
initWorkThread(DEFAULT_NUMBER);
}
public MyThreadPool(int number){
initWorkThread(number);
}

public void execute(Job job){
if(job != null){
synchornized(jobs){
jobs.addLast(job);
jobs.notify(); //加入工作队列,并通知有新任务
}
}
}

public void addWorkers(int num){
//增加工作线程
}

public void removeWorker(){
//删除工作线程
}<pre name="code" class="java"> public void initWorkThread(int num){
         for(int i = 0;i < num;i++){
            Worker worker = new Worker();
            workes.add(worker);
         }
    }}
 

Java并发框架Executor框架:

在HotSpot VM的线程模型中,Java线程被一对一映射为本地操作系统线程。Java线程启动时会创建一个本地操作系统线程;当Java线程终止时,这个操作系统线程也会被回收。可以将此中模式分为两层,在上层中Java通过并发框架创建一定数量的线程;在底层,操作系统将创建的操作系统线程映射到CPU上进行处理。

Executor框架结构:主要分为三大部分:1.任务。包括执行任务需要实现的接口Runnable和Callable。2.任务的执行。包括任务执行机制的核心接口Executor,以及继承自Executor的ExecutorService接口。Executor框架有两个关键类实现了ExecutorService接口(ThreadPoolExecutor和ScheduledThreadPoolExecutor)。3.异步计算的结果。包括接口Future和实现接口Future的FutureTask类。

Executor框架的主要类介绍:ThreadPoolExecutor是线程池的核心实现类,主要由4个组件构成:corePool:核心线程池大小。maximumPool:最大线程池的大小。BlockingQueue:用来暂时保存任务的工作队列。RejectedExecutionHandler:当线程池关闭或已达到饱和时execute()方法将调用的Handler。由此也可以看出实现一个线程池就是基于这几个重要的组件。

ThreadPoolExecutor可以创建3中类型的线程池:

(1)FixedThreadPool,该类的特点就是可以重用固定数量线程的线程池。

执行过程如下:

1.如果当前工作中的线程数量少于corePool的数量,就创建新的线程来执行任务。

2.当线程池的工作中的线程数量达到了corePool,则将任务加入LinkedBlockingQueue。

3.线程执行完1中的任务后会从队列中去任务。

注意LinkedBlockingQueue是*队列,所以可以一直添加新任务到线程池。

(2)SingleThreadExecutor,该类的特点是使用单个工作线程执行任务。

执行过程如下:

1.如果当前工作中的线程数量少于corePool的数量,就创建一个新的线程来执行任务。

2.当线程池的工作中的线程数量达到了corePool,则将任务加入LinkedBlockingQueue。

3.线程执行完1中的任务后会从队列中去任务。

注意:由于在线程池中只有一个工作线程,所以任务可以按照添加顺序执行。

(3)CacheThreadPool,该类的特点是可以根据需要来创建新的线程执行任务,没有特定的corePool。

执行过程如下:

1.首先执行SynchronousQueue.offer(Runnable task)。如果在当前的线程池中有空闲的线程正在执行SynchronousQueue.poll(),那么主线程执行的offer操作与空闲线程执行的poll操作配对成功,主线程把任务交给空闲线程执行。

2.当线程池为空或没有空闲线程时,配对失败,线程池就会创建一个新的线程来执行任务。

3.在创建完新的线程以后,将会执行poll操作。

SynchronousQueue是一个不存储元素阻塞队列,每次要进行offer操作时必须等待poll操作,否则不能继续添加元素。