博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Java并发编程(十一)线程池的使用
阅读量:6991 次
发布时间:2019-06-27

本文共 2288 字,大约阅读时间需要 7 分钟。

 1.new Thread的弊端如下:

  • a. 每次new Thread新建对象性能差。
  • b. 线程缺乏统一管理,可能无限制新建线程,相互之间竞争,及可能占用过多系统资源导致死机或oom。
  • c. 缺乏更多功能,如定时执行、定期执行、线程中断。

相比new Thread,Java提供的四种线程池的好处在于:

  • a.重用线程池中存在的线程,避免因为线程的大量创建和销毁所带来的性能开销 ,完成一项任务的时间T=创建线程的时间+在线程中执行任务的时间+线程销毁的时间, 而线程池的出现可以大大减少创建线程的时间和线程销毁的时间,从而提高app的性能
  • b.能有限的控制线程池的最大并发数,并且大量的线程互相抢占资源而导致的阻塞现象
  • c.对线程池中线程进行有效的跟进,当我们不需要处理的时候可以将它shutdow掉,并提供定时执行以及制定间隔循环执行,

  

2、Java 线程池

Java通过Executors提供四种线程池,分别为:

CachedThreadPool创建一个可缓存线程池,如果线程池长度超过处理需要,可灵活回收空闲线程,若无可回收,则新建线程。在线程空闲60秒后终止线程。
FixedThreadPool 创建一个定长线程池,可控制线程最大并发数,超出的线程会在队列中等待。
ScheduledThreadPool 创建一个定长线程池,支持定时及周期性任务执行。
SingleThreadExecutor 创建一个单线程化的线程池,它只会用唯一的工作线程来执行任务,保证所有任务按照指定顺序(FIFO, LIFO, 优先级)执行。

 

Executors类用于管理Thread对象,简化并发过程,我们可以看到FixedThreadPool的创建过程:

public static ExecutorService newFixedThreadPool(int nThreads) {      return new ThreadPoolExecutor(nThreads, nThreads,                                    0L, TimeUnit.MILLISECONDS,                                    new LinkedBlockingQueue
()); }

显然这四种线程池方法都是返回实现了ExecutorService接口的ThreadPoolExecutor。当然我们也可以直接用ThreadPoolExecutor来自定义更灵活的线程池。

 

我们先看看ThreadPoolExecutor的构建参数:

public ThreadPoolExecutor(int corePoolSize,                           int maximumPoolSize,                          long keepAliveTime,                          TimeUnit unit,                           BlockingQueue
workQueue, ThreadFactory threadFactory, RejectedExecutionHandler handler)

当池子大小小于corePoolSize就新建线程,并处理请求,当池子大小大于corePoolSize,把请求放入workQueue中,池子里的空闲线程就去从workQueue中取任务并处理,当workQueue放不下新入的任务时,新建线程入池,并处理请求,如果池子大小撑到了maximumPoolSize就用RejectedExecutionHandler来做拒绝处理。另外,当池子的线程数大于corePoolSize的时候,多余的线程会等待keepAliveTime长的时间,如果无请求可处理就自行销毁

 

接下来我们来看看CachedThreadPool:

public static ExecutorService newCachedThreadPool() {      return new ThreadPoolExecutor(0, Integer.MAX_VALUE,                                   60L, TimeUnit.SECONDS,                                    new SynchronousQueue
()); }

CachedThreadPool在程序执行时会创建与所需数量相同的线程,然后在它回收旧线程时停止创建新线程,因此是Executor的首选,只有当这种方式会引发问题,或者不符合业务需要时才采用另外的三种Executor提供的线程池

SingleThreadExecutor 就是线程数量为1的FixedThreadPool,如果向SingleThreadExecutor提交多个任务,那么这些任务会排队,每个任务都会在下个任务开始之前就结束,所有任务都用一个线程,并且按照提交的顺序执行。

 线程池用于线程数量比较多时的场景,如果只开启2,3个线程就用线程池,显然会极度的浪费资源

 

转载地址:http://sbbvl.baihongyu.com/

你可能感兴趣的文章
BZOJ 3514 Codechef MARCH14 GERALD07加强版 Link-Cut-Tree+划分树
查看>>
leetcode-Subsets
查看>>
微博爬虫
查看>>
python 回溯法 子集树模板 系列 —— 15、总结
查看>>
dubbo rpc调用,接收到的bean为null原因?
查看>>
高速抓取某个站点内容方法
查看>>
【ES】学习6-多字段搜索1
查看>>
BNU 34974 MATLAB大法好
查看>>
hibernate之多对一单向关联
查看>>
『TensorFlow』0.x_&_1.x版本框架改动汇总
查看>>
JAVA实现将GeoHash转化为相应的经纬度坐标
查看>>
【UML】UML世界的构成
查看>>
WOW.js – 让页面滚动更有趣
查看>>
猫猫学iOS 之CoreLocation反地理编码小Demo输入经纬度得到城市
查看>>
低门槛入门——图灵机器人开发
查看>>
Servlet--j2e中文乱码解决
查看>>
postman中 form-data、x-www-form-urlencoded、raw、binary的区别
查看>>
【java】递归统计本地磁盘所有文件,提取重复文件,JDK8 map迭代
查看>>
Amazon SNS移动推送更新——新增百度云推送和Windows平台支持
查看>>
Xcode6 UIWebView与JavaScript交互(issue fix)
查看>>