【Java】并发之线程池

先看一段我们熟悉的代码:

  1. for (int i = 0; i < 100; i++) {  
  2.     Thread thread = new Thread(new OneTask(i));  
  3.     thread.start();  
  4. }  

其中,OneTask为Runnable接口的实现类。

思考一个问题:当要异步执行大量任务时,比如1000个任务,通过这种方法,就要创建1000个线程。大量线程的创建、销毁,并发执行与线程调度,是一笔很大的性能开销。另外,这么多线程难以很好地管理,有多少任务正在执行、多少任务已经执行完成,无法得知。

线程池,可以很好地处理这些问题。从Java中实现线程池的类为ThreadPoolExecutor。上面的代码,修改为:

  1. LinkedBlockingQueue<Runnable> workQueue = new LinkedBlockingQueue<Runnable>(90);  
  2. ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(51020, TimeUnit.SECONDS, workQueue);  
  3. for (int i = 0; i < 100; i++) {  
  4.     threadPoolExecutor.execute(new OneTask(i));  
  5. }  

ThreadPoolExecutor调用execute方法来“执行”任务(Runnable)实例,其实,说“提交”任务实例更为合理,因为不一定就能立即执行,只是提交到线程池,由线程池来调度执行。

来看一下ThreadPoolExecutor构造方法:

  1. public ThreadPoolExecutor(int corePoolSize,   
  2.                     int maximumPoolSize,   
  3.                     long keepAliveTime,   
  4.                     TimeUnit unit,   
  5.                     BlockingQueue<Runnable> workQueue);  

corePoolSize:线程池核心线程数大小,所谓“核心线程”,即在线程池中必不可少的,即使该线程负责执行的任务执行完毕,也不可少销毁自己,必须留在池中,以等待执行新的任务。

maximumPoolSize:线程池最大线程数大小,要注意,最大线程数总会大于或等于核心线程数。为什么会有大于?因为,除了核心线程外,线程池还可以创建一些新线程加入池中,这些新线程不同于核心线程,它们完成任务,空闲一定的时间后便会销毁掉。而这个时间,由下面两个参数决定。

keepAliveTime:非核心线程空闲时保留在池中多长时间,除非有新任务要求它去执行,否则过了这段时间,该线程会销毁掉。TimeUnit为时间单位类,如传参TimeUnit.SECONDS,表示keepAliveTime的单位为秒。

workQueue:一个BlockingQueue类型的参数,我们暂且简单地理解为一个队列。线程池使用这个队列来装载等待的任务。上面代码中,使用了BlockingQueue接口的一个实现类LinkedBlockingQueue,它的构造方法有一个参数capacity,决定了线程池等待队列的容量,即最多可以允许多少个任务加入等待队列。

下面分析下线程池创建、提交任务、任务等待、执行任务的过程。

a. 当ThreadPoolExecutor刚构造时,池中是还没有线程的。

b. 当调用execute()方法提交任务时,线程池会创建一个线程,来执行该任务,此时,线程池当前的线程数(pool size)为1。

c. 继续提交任务,继续创建线程(假设前面的任务都还没有这么快执行完),池中线程数递增1,依此类推。当达到corePoolSize个时,就不再创建新线程,新提交的任务就会进入等待队列,等到corePoolSize个线程中,有某个线程执行完任务时,等待队列中的任务才得以进入线程池中执行。

d.(继续假设前面的任务都还没有这么快执行完)继续提交任务,继续加入等待队列,当超出了等待队列所能容纳的最大限度(BlockingQueue的capacity值)时。前面说的maximumPoolSize参数要发挥作用了。当设置的maximumPoolSize值大于corePoolSize值,则此时线程池会创建新线程来执行该任务,线程池中线程数递增1。当线程池中的线程数达到了maximumPoolSize个,就不能再创建了,否则会报RejectedExecutionException异常。

e.线程执行完一个任务后,会从等待队列中取出新任务,然后执行新任务,这个过程,等待队列的任务数会减少。当线程池也渐渐执行完所有任务后,corePoolSize个的x线程(核心线程)继续存活不会销毁。而那些非核心线程(最多maximumPoolSize-corePoolSize个),过了keepAliveTime时间后便会被销毁。


Executors类是一工厂类,提供了一些创建常用ThreadPoolExecutor的方法。贴一下这些方法的源码,会更容易理解。

a. 创建固定个数的线程池执行器:

  1. public static ExecutorService newFixedThreadPool(int nThreads) {  
  2.     return new ThreadPoolExecutor(nThreads, nThreads,  
  3.                                   0L, TimeUnit.MILLISECONDS,  
  4.                                   new LinkedBlockingQueue<Runnable>());  
  5. }  

b. 创建单个线程的线程池执行器:

  1. public static ExecutorService newSingleThreadExecutor() {  
  2.     return new FinalizableDelegatedExecutorService  
  3.         (new ThreadPoolExecutor(11,  
  4.                                 0L, TimeUnit.MILLISECONDS,  
  5.                                 new LinkedBlockingQueue<Runnable>()));  
  6. }  

单线程执行器,可保证按顺序地执行任务。

c.创建缓存的线程池执行器:
  1. public static ExecutorService newCachedThreadPool() {  
  2.     return new ThreadPoolExecutor(0, Integer.MAX_VALUE,  
  3.                                   60L, TimeUnit.SECONDS,  
  4.                                   new SynchronousQueue<Runnable>());  
  5. }  
缓存线程执行器,执行大量的耗时短的任务,能很好地改善性能。

@容新华技术博客 - http://blog.csdn.net/rongxinhua - 原创文章,转载请注明出处


基于SSM框架的智能家政保洁预约系统,是一个旨在提高家政保洁服务预约效率和管理水平的平台。该系统通过集成现代信息技术,为家政公司、家政服务人员和消费者提供了一个便捷的在线预约和管理系统。 系统的主要功能包括: 1. **用户管理**:允许消费者注册、登录,并管理他们的个人资料和预约历史。 2. **家政人员管理**:家政服务人员可以注册并更新自己的个人信息、服务类别和服务时间。 3. **服务预约**:消费者可以浏览不同的家政服务选项,选择合适的服务人员,并在线预约服务。 4. **订单管理**:系统支持订单的创建、跟踪和管理,包括订单的确认、完成和评价。 5. **评价系统**:消费者可以在家政服务完成后对服务进行评价,帮助提高服务质量和透明度。 6. **后台管理**:管理员可以管理用户、家政人员信息、服务类别、预约订单以及处理用户反馈。 系统采用Java语言开发,使用MySQL数据库进行数据存储,通过B/S架构实现用户与服务的在线交互。系统设计考虑了不同用户角色的需求,包括管理员、家政服务人员和普通用户,每个角色都有相应的权限和功能。此外,系统还采用了软件组件化、精化体系结构、分离逻辑和数据等方法,以便于未来的系统升级和维护。 智能家政保洁预约系统通过提供一个集中的平台,不仅方便了消费者的预约和管理,也为家政服务人员提供了一个展示和推广自己服务的机会。同时,系统的后台管理功能为家政公司提供了强大的数据支持和决策辅助,有助于提高服务质量和管理效率。该系统的设计与实现,标志着家政保洁服务向现代化和网络化的转型,为管理决策和控制提供保障,是行业发展中的重要里程碑。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值