Java并发编程之线程池实现原理

概述

相信如果问你,Java中由几种线程池,你也能很快的回答出四种线程池:
newCachedThreadPoolnewFixedThreadPoolnewSingleThreadExecutornewScheduledThreadPool,那么,你了解过这些线程池的实现原理吗?还记得它们有什么区别吗?跟着笔者复习一下。

线程池的基本参数

public ThreadPoolExecutor(int corePoolSize,
                              int maximumPoolSize,
                              long keepAliveTime,
                              TimeUnit unit,
                              BlockingQueue<Runnable> workQueue,
                              ThreadFactory threadFactory,
                              RejectedExecutionHandler handler);
corePoolSize:核心线程数量
maximumPoolSize:池内最大线程数量
keepAliveTime:线程存活的时间
unit:存活时间单位
workQueue:阻塞队列
threadFactory:线程工厂类,默认为Executors.defaultThreadFactory()
handler:拒绝策略(比如核心线程已到达最大数量,阻塞队列已满等情况的处理)

newCachedThreadPool

可缓存线程池

public static ExecutorService newCachedThreadPool() {
	//池内最大线程数量为:Integer.MAX_VALUE
    return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
                                  60L, TimeUnit.SECONDS,
                                  new SynchronousQueue<Runnable>());
}

注意:SynchronousQueue是一个不存储元素的阻塞队列,每一个put必须等待一个take操作,否则不能继续添加元素。并且他支持公平访问队列,属于无界阻塞队列

特点:

1、线程数无限制。
2、有空闲线程则复用空闲线程,若无空闲线程则新建线程。
3、一定程序减少频繁创建/销毁线程,减少系统开销。

newFixedThreadPool

固定线程数量的线程池

public static ExecutorService newFixedThreadPool(int nThreads) {
	//核心线程数量就是总线程数量
	//线程不会回收
    return new ThreadPoolExecutor(nThreads, nThreads,
                                  0L, TimeUnit.MILLISECONDS,
                                  new LinkedBlockingQueue<Runnable>());
}

注意:LinkedBlockingQueue一个由链表结构组成的有界阻塞队列

特点:

1、可控制线程最大并发数(同时执行的线程数)。
2、超出的线程会在队列中等待。

newSingleThreadExecutor

单线程化的线程池

public static ExecutorService newSingleThreadExecutor() {
	//单个线程的线程池
    return new FinalizableDelegatedExecutorService
        (new ThreadPoolExecutor(1, 1,
                                0L, TimeUnit.MILLISECONDS,
                                new LinkedBlockingQueue<Runnable>()));
}

特点:

1、有且仅有一个工作线程执行任务。
2、所有任务按照指定顺序执行,即遵循队列的入队出队规则。

newScheduledThreadPool

定时执行线程池

public static ScheduledExecutorService newSingleThreadScheduledExecutor() {
    return new DelegatedScheduledExecutorService
        (new ScheduledThreadPoolExecutor(1));
}

特点:支持定时以指定周期循环执行任务。

注意:前三种线程池是ThreadPoolExecutor不同配置的实例,最后一种是ScheduledThreadPoolExecutor的实例。

线程池原理

从任务提交的流程角度来看,对于使用线程池的外部来说,线程池的机制是这样的:

1、如果正在运行的线程数 < coreSize,马上创建核心线程执行该task,不排队等待。
2、如果正在运行的线程数 >= coreSize,把该task放入阻塞队列(BlockingQueue)
3、如果队列已满且正在运行的线程数 < maximumPoolSize,创建新的非核心线程执行该task。
4、如果队列已满且正在运行的线程数 >= maximumPoolSize,线程池调用handler的reject方法拒绝本次提交

简单理解就是:核心线程->阻塞队列->非核心线程->handler拒绝提交。

阻塞队列

阻塞队列在Java是一种非常常见的数据结构,常用的阻塞队列有七种,在线程池中等场景下较为常见。

有界队列

1、初始的poolSize < corePoolSize,提交的runnable任务,会直接做为new一个Thread的参数,立马执行 。
2、当提交的任务数超过了corePoolSize,会将当前的runable提交到一个BlockQueue中。
3、有界队列满了之后,如果poolSize < maximumPoolsize时,会尝试new 一个Thread的进行救急处理,立马执行对应的runnable任务
4、如果3中也无法处理了,就会走到第四步执行reject操作

无界队列

与有界队列相比,除非系统资源耗尽,否则无界的任务队列不存在任务入队失败的情况。当有新的任务到来,系统的线程数小于corePoolSize时,则新建线程执行任务。当达到corePoolSize后,就不会继续增加,若后续仍有新的任务加入,而没有空闲的线程资源,则任务直接进入队列等待。若任务创建和处理的速度差异很大,无界队列会保持快速增长,直到耗尽系统内存。 当线程池的任务缓存队列已满并且线程池中的线程数目达到maximumPoolSize,如果还有任务到来就会采取任务拒绝策略。

ArrayBlockingQueue

由数组结构组成的有界阻塞队列

此队列按照先进先出(FIFO)的原则对元素进行排序,但是默认情况下不保证线程公平的访问队列,即如果队列满了,那么被阻塞在外面的线程对队列访问的顺序是不能保证线程公平(即先阻塞,先插入)的

LinkedBlockingQueue

一个由链表结构组成的有界阻塞队列:此队列按照先出先进的原则对元素进行排序

PriorityBlockingQueue

支持优先级的无界阻塞队列

DelayQueue

支持延时获取元素的无界阻塞队列,即可以指定多久才能从队列中获取当前元素。

SynchronousQueue

不存储元素的阻塞队列,每一个put必须等待一个take操作,否则不能继续添加元素。并且他支持公平访问队列,属于无界阻塞队列。

LinkedTransferQueue

由链表结构组成的无界阻塞队列TransferQueue。相对于其他阻塞队列,多了tryTransfer和transfer方法

transfer方法:如果当前有消费者正在等待接收元素(take或者待时间限制的poll方法),transfer可以把生产者传入的元素立刻传给消费者。如果没有消费者等待接收元素,则将元素放在队列的tail节点,并等到该元素被消费者消费了才返回。
tryTransfer方法:用来试探生产者传入的元素能否直接传给消费者。如果没有消费者在等待,则返回false。和上述方法的区别是该方法无论消费者是否接收,方法立即返回。而transfer方法是必须等到消费者消费了才返回。

LinkedBlockingDeque

链表结构的双向阻塞队列,优势在于多线程入队时,减少一半的竞争。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
图像识别技术在病虫害检测中的应用是一个快速发展的领域,它结合了计算机视觉和机器学习算法来自动识别和分类植物上的病虫害。以下是这一技术的一些关键步骤和组成部分: 1. **据收集**:首先需要收集大量的植物图像据,这些据包括健康植物的图像以及受不同病虫害影响的植物图像。 2. **图像预处理**:对收集到的图像进行处理,以提高后续分析的准确性。这可能包括调整亮度、对比度、去噪、裁剪、缩放等。 3. **特征提取**:从图像中提取有助于识别病虫害的特征。这些特征可能包括颜色、纹理、形状、边缘等。 4. **模型训练**:使用机器学习算法(如支持向量机、随机森林、卷积神经网络等)来训练模型。训练过程中,算法会学习如何根据提取的特征来识别不同的病虫害。 5. **模型验证和测试**:在独立的测试集上验证模型的性能,以确保其准确性和泛化能力。 6. **部署和应用**:将训练好的模型部署到实际的病虫害检测系统中,可以是移动应用、网页服务或集成到智能农业设备中。 7. **实时监测**:在实际应用中,系统可以实时接收植物图像,并快速给出病虫害的检测结果。 8. **持续学习**:随着时间的推移,系统可以不断学习新的病虫害样本,以提高其识别能力。 9. **用户界面**:为了方便用户使用,通常会有一个用户友好的界面,显示检测结果,并提供进一步的指导或建议。 这项技术的优势在于它可以快速、准确地识别出病虫害,甚至在早期阶段就能发现问题,从而及时采取措施。此外,它还可以减少对化学农药的依赖,支持可持续农业发展。随着技术的不断进步,图像识别在病虫害检测中的应用将越来越广泛。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值