三、一个用队列处理线程池例子

  1. package demo;
  2. import java.util.Queue;
  3. import java.util.concurrent.ArrayBlockingQueue;
  4. import java.util.concurrent.ThreadPoolExecutor;
  5. import java.util.concurrent.TimeUnit;
  6. public class ThreadPoolExecutorTest
  7. {
  8. private static int queueDeep = 4;
  9. public void createThreadPool()
  10. {
  11. /*
  12. * 创建线程池,最小线程数为2,最大线程数为4,线程池维护线程的空闲时间为3秒,
  13. 缓冲队列为4,线程执行时间是3秒。
  14. */
  15. ThreadPoolExecutor tpe = new ThreadPoolExecutor(2, 4, 3, TimeUnit.SECONDS, new ArrayBlockingQueue<Runnable>(queueDeep),
  16. new ThreadPoolExecutor.DiscardOldestPolicy()); //这里采取的是抛弃旧的任务
  17. // 向线程池中添加 10 个任务
  18. for (int i = 0; i < 10; i++)
  19. {
  20. try
  21. {
  22. Thread.sleep(1);
  23. }
  24. catch (InterruptedException e)
  25. {
  26. e.printStackTrace();
  27. }
  28. while (getQueueSize(tpe.getQueue()) >= queueDeep)
  29. {
  30. System.out.println("队列已满,等3秒再添加任务");
  31. try
  32. {
  33. Thread.sleep(3000);
  34. }
  35. catch (InterruptedException e)
  36. {
  37. e.printStackTrace();
  38. }
  39. }
  40. TaskThreadPool ttp = new TaskThreadPool(i);
  41. System.out.println("put i:" + i);
  42. tpe.execute(ttp);
  43. }
  44. tpe.shutdown();
  45. }
  46. private synchronized int getQueueSize(Queue queue)
  47. {
  48. return queue.size();
  49. }
  50. public static void main(String[] args)
  51. {
  52. ThreadPoolExecutorTest test = new ThreadPoolExecutorTest();
  53. test.createThreadPool();
  54. }
  55. class TaskThreadPool implements Runnable
  56. {
  57. private int index;
  58. public TaskThreadPool(int index)
  59. {
  60. this.index = index;
  61. }
  62. public void run()
  63. {
  64. System.out.println(Thread.currentThread() + " index:" + index);
  65. try
  66. {
  67. Thread.sleep(3000);
  68. }
  69. catch (InterruptedException e)
  70. {
  71. e.printStackTrace();
  72. }
  73. }
  74. }
  75. }

说明:

这里执行的结果为:

put i:0                      0加入进去池子
Thread[pool-1-thread-1,5,main] index:0     0开始执行
put i:1                      1加入进去池子
Thread[pool-1-thread-2,5,main] index:1         1开始执行
put i:2                      2加入缓冲
put i:3                      3加入缓冲
put i:4                      4加入缓冲
put i:5                      5加入缓冲
队列已满,等3秒再添加任务

(上述代码首先一次性执行,会在这里停一会,因为添加线程不需要时间)
Thread[pool-1-thread-1,5,main] index:2    2开始执行
Thread[pool-1-thread-2,5,main] index:3    3开始执行
put i:6                     6加入缓冲
put i:7                     7加入缓冲
队列已满,等3秒再添加任务

(会停一会,因为任务执行要3秒时间,2,3,4,5会先执行2,3 ,因为2,3先进入缓冲队列)
Thread[pool-1-thread-1,5,main] index:4
Thread[pool-1-thread-2,5,main] index:5
put i:8
put i:9

(停一会,任务执行要3秒,)
Thread[pool-1-thread-1,5,main] index:6
Thread[pool-1-thread-2,5,main] index:7

(要停一会,任务执行要3秒)
Thread[pool-1-thread-1,5,main] index:8
Thread[pool-1-thread-2,5,main] index:9

(执行完毕)

ps:这里是当队列已满时线程就一直等待了,不会再新创建线程,所以一直就只有1和2两个线程来执行。

如果把

  1. while (getQueueSize(tpe.getQueue()) >= queueDeep){}

这一段去掉,那么执行结果为:

put i:0
Thread[pool-1-thread-1,5,main] index:0
put i:1
Thread[pool-1-thread-2,5,main] index:1
put i:2
put i:3
put i:4
put i:5
put i:6
Thread[pool-1-thread-3,5,main] index:6
put i:7
Thread[pool-1-thread-4,5,main] index:7
put i:8
put i:9
Thread[pool-1-thread-1,5,main] index:4
Thread[pool-1-thread-2,5,main] index:5
Thread[pool-1-thread-3,5,main] index:8
Thread[pool-1-thread-4,5,main] index:9

ps:这个执行顺序是0,1两个任务先进来,分别由线程1,2来执行,然后2,-5进来,队列满,6任务进来,因为队列已满,且1,2线程还未执行完,没有可用的线程,所以创建新的线程来运行6。7任务同理。然后8任务进来,队列已满,且1,2,3,4线程未执行完,线程数又等于了最多4个线程的限制,这时看线程池的执行策略为DiscardOldestPolicy,就是抛弃旧的任务,故开始进队列的2任务被抛弃,3任务同理,8,9任务进入队列,然后这时1-4线程已经执行完自己的任务,开始执行队列中的4,5,8,9

如果更改执行策略,那么相应的结果也会不一样,如果不希望有任务被抛弃,那么可以采用CallerRunsPolicy()策略。

线程池系列三:ThreadPoolExecutor讲解的更多相关文章

  1. 《java.util.concurrent 包源码阅读》13 线程池系列之ThreadPoolExecutor 第三部分

    这一部分来说说线程池如何进行状态控制,即线程池的开启和关闭. 先来说说线程池的开启,这部分来看ThreadPoolExecutor构造方法: public ThreadPoolExecutor(int ...

  2. 《java.util.concurrent 包源码阅读》11 线程池系列之ThreadPoolExecutor 第一部分

    先来看ThreadPoolExecutor的execute方法,这个方法能体现出一个Task被加入到线程池之后都发生了什么: public void execute(Runnable command) ...

  3. 《java.util.concurrent 包源码阅读》12 线程池系列之ThreadPoolExecutor 第二部分

    接着说worker线程是如何工作的.ThreadPoolExecutor有一个成员类叫Worker,所起到的作用就是线程池worker线程的作用. private final class Worker ...

  4. java线程池系列(1)-ThreadPoolExecutor实现原理

    前言 做java开发的,一般都避免不了要面对java线程池技术,像tomcat之类的容器天然就支持多线程. 即使是做偏后端技术,如处理一些消息,执行一些计算任务,也经常需要用到线程池技术. 鉴于线程池 ...

  5. 线程池系列二:ThreadPoolExecutor讲解

    一.简介 1)线程池类为 java.util.concurrent.ThreadPoolExecutor,常用构造方法为: ThreadPoolExecutor(int corePoolSize, i ...

  6. Java多线程系列--“JUC线程池”04之 线程池原理(三)

    转载请注明出处:http://www.cnblogs.com/skywang12345/p/3509960.html 本章介绍线程池的生命周期.在"Java多线程系列--“基础篇”01之 基 ...

  7. 线程池系列一:线程池作用及Executors方法讲解

    线程池的作用: 线程池作用就是限制系统中执行线程的数量.     根据系统的环境情况,可以自动或手动设置线程数量,达到运行的最佳效果:少了浪费了系统资源,多了造成系统拥挤效率不高.用线程池控制线程数量 ...

  8. Java多线程系列——线程池原理之 ThreadPoolExecutor

    ThreadPoolExecutor 简介 ThreadPoolExecutor 是线程池类. 通俗的讲,它是一个存放一定数量线程的线程集合.线程池允许多个线程同时运行,同时运行的线程数量就是这个线程 ...

  9. C# 多线程学习系列三之CLR线程池系列之ThreadPool

    一.CLR线程池 1.进程和CLR的关系一个进程可以只包含一个CLR,也可以包含多个CLR2.CLR和AppDomain的关系一个CLR可以包含多个AppDomain3.CLR和线程池的关系一个CLR ...

随机推荐

  1. vue父子组件通信传值

    父组件 -> 子组件 通过props来进行通信 父组件代码: <Children :dataName = "dataContent" /> //dataName: ...

  2. 通过force index了解的MySQL查询的性能优化

    查询是数据库技术中最常用的操作.查询操作的过程比较简单,首先从客户端发出查询的SQL语句,数据库服务端在接收到由客户端发来的SQL语句后, 执行这条SQL语句,然后将查询到的结果返回给客户端.虽然过程 ...

  3. 三 概要模式 3) MR计数器计数 。无 reduce 计数

    计数器模式讲解:         先讲一下,就是说只用 Map 阶段  不需要 Reduce . 也就是说去掉了中间输出,而是Map 直接输出结果.大大提高了 MR 的效率且节省了 MR 中间输出读入 ...

  4. [Typescript] Promise based delay function using async / await

    Learn how to write a promise based delay function and then use it in async await to see how much it ...

  5. 对象逆序列化报错:java.lang.ClassNotFoundException

    简单的想从保存的对象中又一次解析出对象.用了逆序列化,但是报错: java.lang.ClassNotFoundException: xxxxxxxxxxxx at java.net.URLClass ...

  6. mysql-高级语言语法

    一.注释 从#字符到行尾 从'-- '序列到行尾.两个破折号之后至少要有一个空格符或制表符. 二.设置变量 用户变量的形式为@var_name,其中变量名varname可以有当前字符集的文字数字字符. ...

  7. netty学习(二)--传统的bio编程

    网络编程的基本模型是Client/Server模型.也就是两个进程之间进行相互通信,当中服务端提供位置信息( 绑定ip地址和监听port),client通过连接操作向服务端监听的地址发送连接请求,通过 ...

  8. android JNI 一维数组、二维数组的访问与使用

    在JNI中访问JAVA类中的整型.浮点型.字符型的数据比较简单,举一个简单的例子,如下: //得到类名 jclass cls = (*env)->GetObjectClass(env, obj) ...

  9. Mysql-in查询问题

    Mysql-in查询问题 标签(空格分隔): mysql 问题:mysql用in语法查询出来的数据少了好多! 我的实际情况: 数据表: content字段记录着一些选项的id,多个选项用逗号隔开,比如 ...

  10. Error creating bean with name 'testController': Injection of resource dependencies failed;

    启动ssm项目报错: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 't ...