线程池,顾名思义,放线程的池子嘛,这个池子可以存放多少线程取决于你自己采用什么样的线程池,你的硬件资源,以及并发线程的数量。JDK提供了下面的四种线程池:

固定线程数的线程池

  1. 最简单的

在Java中创建一个线程池,这很简单,只需要两行代码。

ExecutorService executor = Executor.newFixedTreadPool(6);//固定线程是6
//线程一般设置成processor核心数的倍数,因为我这台机器是6核的,所以设成6。这也是充分利用硬件嘛 //执行线程任务
executor.execute(new Runnable(){
@Override
public void run(){
//do nothing
}
}) executor.shutdown();

Executor是Java并发包中提供的,用来创造不同类型的线程池。

Attention

但是在多人合作或者是一些部署上线的项目里,是不允许去使用这种方法的,因为它是有性能隐患的。

Executors在创建线程池的时候,用的是new LinkedBlockingQueue(),它这个队列本身是无边界的,但是线程是固定数量的。这就意味着,在程序运行的过程中,最多会有N个线程在处于活动状态。每次有新的任务来就会等待,直到有线程处于空闲状态。所有的线程都会处于线程池里里面,直到shutdown()的执行。

它的问题就在于来者不拒,只要有任务来,你就进队列等着。在入队列和出队列用的并不是同一个lock,在多processor的机器上,是可以做到真正意义上的并行的。拿经典的生产者和消费者来举例子,在同一个时间点,有的在消费,有的在生产。

这种线程池不会销毁线程,不会拒绝任务,固定线程数。所以如果不停的加入任务,会导致很糟糕的内存占用,老年代可能会被占满。

  1. 稍复杂的(可以延时执行,也可以执行带返回值的任务)
public static void main(String[] args) throws InterruptedException, ExecutionException {
TestThread testThread = new TestThread();
System.out.println(testThread.processors); ScheduledExecutorService scheduledExecutorService = Executors.newScheduledThreadPool(6);
FutureTask<String> futureTask = new FutureTask<>(new Callable<String>() {
@Override
public String call() throws Exception {
return Thread.currentThread().getName();
}
});
scheduledExecutorService.submit(futureTask); //获取返回值
String result = futureTask.get();
System.out.println("result :"+result); //执行延时任务
scheduledExecutorService.schedule(new Runnable() {
@Override
public void run() {
System.out.println(Thread.currentThread().getName()+": bomb!");
}
},3L,TimeUnit.SECONDS);
}

Output:

result :pool-1-thread-1

pool-1-thread-1: bomb!

缓存的线程池

核心池大小为0,线程池最大线程数目为最大整型,这意味着所有的任务一提交就会wait****。当线程池中的线程有60s没有执行任务就会被Kill,阻塞队列为SynchronousQueue。SynchronousQueue的take操作需要put操作等待,put操作需要take操作等待,否则会阻塞(线程池的阻塞队列不能存储,所以当目前线程处理忙碌状态时,会开辟新的线程来处理请求**),线程进入wait set。

总结一下这是一个可以无限扩大的线程池;适合处理执行时间比较小的任务;线程空闲时间超过60s就会被Kill,所以长时间处于空闲状态的时候,这种线程池几乎不占用资源,因为它压根没有线程在里面;阻塞队列没有存储空间,只要请求到来,就必须找到一条空闲线程去处理这个请求,找不到则在线程池新开辟一条线程。

如果主线程提交任务的速度远远大于CachedThreadPool的处理速度,则CachedThreadPool会不断地创建新线程来执行任务,这样有可能会导致系统耗尽CPU和内存资源,所以在使用该线程池时,要注意控制并发的任务数。如果是一个不断增长的任务需求,很容易就会到性能瓶颈,它会不停的创建新的线程。

 ExecutorService cachedThreadPool = Executors.newCachedThreadPool();
for (int i = 0; i < 10; i++) {
cachedThreadPool.execute(new Runnable() {
@Override
public void run() {
System.out.println(Thread.currentThread().getName());
}
});
}
cachedThreadPool.shutdown();

Output:

pool-1-thread-2

pool-1-thread-6

pool-1-thread-1

pool-1-thread-7

pool-1-thread-8

pool-1-thread-3

pool-1-thread-5

pool-1-thread-9

pool-1-thread-4

pool-1-thread-10

单个线程的线程池

SingleThreadExecutor 是使用单个worker线程的Executor。只有一种情况会有新的线程加入线程池,那就是原有的线程运行时有抛出异常,这时就会有创建的新的线程来替代它的工作。

拿生产者消费者模型来说的话,这就是一个单一消费者的模型

(ps.一般可以用来做一些日志记录

 public static void main(String[] args) {
// 永远是一条线程
ExecutorService singleThreadPool = Executors.newSingleThreadExecutor();
for (int i = 0; i < 10; i++) {
final int j = i;
singleThreadPool.execute(new Runnable() {
@Override
public void run() {
System.out.println(Thread.currentThread().getName() + ":" + j);
}
});
}
singleThreadPool.shutdown(); }

Output:

pool-1-thread-1:0

pool-1-thread-1:1

pool-1-thread-1:2

pool-1-thread-1:3

pool-1-thread-1:4

pool-1-thread-1:5

pool-1-thread-1:6

pool-1-thread-1:7

pool-1-thread-1:8

pool-1-thread-1:9

最新文章

  1. [数学]内接多边形求pi
  2. Android DownloadProvider学习
  3. 学生信息管理系统(自己辛辛苦苦做了几天,虽然简陋,也凑合吧,bug不算太严重,主要是格式不太很完美)
  4. linux命令--dig
  5. java Long的iniValue出错
  6. fiddler for mac
  7. DZ升级到X3.2后,UCenter用户管理中心进不了了
  8. Hyper-V中安装CentOS分辨率修改
  9. motan源码分析四:客户端调用服务
  10. Keil 二进制数输入宏
  11. salt自动化部署
  12. testng-result中文乱码问题
  13. VS Code 快捷键(中英文对照版)
  14. .Net Core 1.0升级2.0(xproj项目迁移到.csproj )
  15. kafka 常用参数
  16. MySQL:测试题
  17. 用canvas把页面中所有元素的轮廓绘制出来
  18. Linux平台下源码安装mysql多实例数据库
  19. 12.18daily_scrum
  20. (笔记)Mysql命令create:创建数据库

热门文章

  1. baiduMap试手《办理进京证和市区警察查询进京证的地址浏览》
  2. 文件夹管理工具(MVC+zTree+layer)
  3. 基于python实现的三方组件----Celery
  4. 【设计模式】行为型11解释器模式(Interpreter Pattern)
  5. K-近邻算法介绍与代码实现
  6. 每天学点node系列-stream
  7. 思维导图xmind的使用方法
  8. Spring 入门程序
  9. 利用jsonconvert来转换json数据格式 (对象转为json)
  10. 设计模式-访问者模式(Visitor)