资讯专栏INFORMATION COLUMN

java 线程池

tolerious / 2185人阅读

摘要:二线程池状态当创建线程池后,初始时,线程池处于状态。当线程池处于或状态,并且所有工作线程已经销毁,任务缓存队列已经清空或执行结束后,线程池被设置为状态。

一、什么时候使用线程池

(1)、减少了创建和销毁线程的次数,每个工作线程都可以被重复利用,可执行多个任务。
(2)、可以根据系统的承受能力,调整线程池中工作线线程的数目,防止因为消耗过多的内存,而把服务器累趴下(每个线程需要大约1MB内存,线程开的越多,消耗的内存也就越大,最后死机),具体可以使用Runtime.getRuntime().availableProcessors()查看虚拟机返回可用处理器的数量()。

二、线程池状态

(1)、RUNNING : 当创建线程池后,初始时,线程池处于RUNNING状态。
(2)、SHUTDOWN : 如果调用了shutdown()方法,则线程池处于SHUTDOWN状态,此时线程池不能够接受新的任务,它会等待所有任务执行完毕。
(3)、STOP : 如果调用了shutdownNow()方法,则线程池处于STOP状态,此时线程池不能接受新的任务,并且会去尝试终止正在执行的任务。
(4)、TIDYING : 所有任务已终止,workerCount为零,线程转换到状态TIDYING,运行terminate()方法。
(5)、TERMINATED : 当线程池处于SHUTDOWN或STOP状态,并且所有工作线程已经销毁,任务缓存队列已经清空或执行结束后,线程池被设置为TERMINATED状态。

三、初始化参数

(1)、corePoolSize : 线程核心线程数,当有任务进来时,当前运行的线程数量小于核心线程就会在创建线程,当前线程等于核心线程数时,任务就会被放入队列里面,请参照 (5)。
(2)、maximumPoolSize : 线程池中允许的最大线程数,当线程池的线程 >= 核心线程数时,并且队列已经放满了任务,这时线程池就会在创建线程去执行任务。
(3)、keepAliveTime : 当前线程数大于核心线程数时,线程池就会找机会干掉多余的线程,当没有任务可以执行时,线程池会给全部线程定一个等待时间,如果过了这个时间,没有获得任务进来就直接干掉线程 (当前线程数等于或多于核心线程数时,线程池首选将任务加入队列,而不添加新的线程)。
(4)、unit : keepAliveTime的时间单位。
(5)、workQueue : 在执行任务之前用于保留任务的队列,(当前线程数大于等于核心线程数时,再有任务进来就会被放到队列里面)。
常用队列 :
(1)、LinkedBlockingQueue,LinkedBlockingQueue是一个无界队列,存储方式使用的是链表
(1)、ArrayBlockingQueue,ArrayBlockingQueue是一个有界队列,存储方式使用的是数组
(1)、SynchronousQueue,SynchronousQueue是一个同步队列没有任何内部容量,直接将任务交给线程,(SynchronousQueue通常要求最大线程数是无界的以避免拒绝新提交的任务)。

四、使用

官方文档强烈建议程序员使用较为方便的 Executors 工厂方法 Executors.newCachedThreadPool()(无界线程池,可以进行自动线程回收)、Executors.newFixedThreadPool(int)(固定大小线程池)和 Executors.newSingleThreadExecutor()(单个后台线程)

五、运行流程

(1)、当提交一个任务!
public void execute(Runnable command) {

</>复制代码

  1. if (command == null)
  2. throw new NullPointerException();
  3. int c = ctl.get();
  4. /*
  5. 先判断是否工作线程是否小于核心线程,如果小于就添加到调用添加工作方法。
  6. 添加成功就返回。
  7. 如果当前线程大于等于核心线程就将任务放进队列里面。
  8. */
  9. if (workerCountOf(c) < corePoolSize) {
  10. if (addWorker(command, true))
  11. ...
  12. }
  13. if (isRunning(c) && workQueue.offer(command)) {
  14. ...
  15. }
  16. }

(2)、执行任务
private boolean addWorker(Runnable firstTask, boolean core) {

</>复制代码

  1. ...
  2. boolean workerStarted = false;
  3. boolean workerAdded = false;
  4. Worker w = null;
  5. try {
  6. final ReentrantLock mainLock = this.mainLock;
  7. /*
  8. 创建一个工作线程,将任务放进去
  9. */
  10. w = new Worker(firstTask);
  11. final Thread t = w.thread;
  12. if (t != null) {
  13. mainLock.lock();
  14. try {
  15. // Recheck while holding lock.
  16. // Back out on ThreadFactory failure or if
  17. // shut down before lock acquired.
  18. int c = ctl.get();
  19. int rs = runStateOf(c);
  20. if (rs < SHUTDOWN ||
  21. (rs == SHUTDOWN && firstTask == null)) {
  22. if (t.isAlive()) // precheck that t is startable
  23. throw new IllegalThreadStateException();
  24. /*
  25. 将所有工作放到Set集合,进行管理
  26. */
  27. workers.add(w);
  28. int s = workers.size();
  29. if (s > largestPoolSize)
  30. largestPoolSize = s;
  31. workerAdded = true;
  32. }
  33. } finally {
  34. mainLock.unlock();
  35. }
  36. if (workerAdded) {
  37. /*
  38. 执行任务线程
  39. */
  40. t.start();
  41. workerStarted = true;
  42. }
  43. }
  44. } finally {
  45. if (! workerStarted)
  46. addWorkerFailed(w);
  47. }
  48. return workerStarted;
  49. }

只想写一点文章希望大家,多多指点。

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/69533.html

相关文章

  • Java线程

    摘要:中的线程池是运用场景最多的并发框架。才是真正的线程池。存放任务的队列存放需要被线程池执行的线程队列。所以线程池的所有任务完成后,它最终会收缩到的大小。饱和策略一般情况下,线程池采用的是,表示无法处理新任务时抛出异常。 Java线程池 1. 简介 系统启动一个新线程的成本是比较高的,因为它涉及与操作系统的交互,这个时候使用线程池可以提升性能,尤其是需要创建大量声明周期很短暂的线程时。Ja...

    jerry 评论0 收藏0
  • 后端ing

    摘要:当活动线程核心线程非核心线程达到这个数值后,后续任务将会根据来进行拒绝策略处理。线程池工作原则当线程池中线程数量小于则创建线程,并处理请求。当线程池中的数量等于最大线程数时默默丢弃不能执行的新加任务,不报任何异常。 spring-cache使用记录 spring-cache的使用记录,坑点记录以及采用的解决方案 深入分析 java 线程池的实现原理 在这篇文章中,作者有条不紊的将 ja...

    roadtogeek 评论0 收藏0
  • java 四种线程的使用

    摘要:四种线程池的使用介绍的弊端及四种线程池的使用,线程池的作用线程池作用就是限制系统中执行线程的数量。相比,提供的四种线程池的好处在于重用存在的线程,减少对象创建消亡的开销,性能佳。延迟执行描述创建一个定长线程池,支持定时及周期性任务执行。 java 四种线程池的使用 介绍new Thread的弊端及Java四种线程池的使用 1,线程池的作用 线程池作用就是限制系统中执行线程的数量。 ...

    gggggggbong 评论0 收藏0
  • Java 线程

    系统启动一个线程的成本是比较高,使用线程池可以很好地提高性能,尤其是当程序中需要创建大量生存期很短暂的线程时 线程池在系统启动时即创建大量空闲线程,将一个Runnable、Callable对象—–>传给线程池—–>线程池启动里面的一个线程来执行它们的run()或者call()方法———->当线程执行体执行完成后,线程并不会死亡,而是再次返回线程池成为空闲状态,等待下一个Runnable、Calla...

    ctriptech 评论0 收藏0
  • 跟着阿里p7一起学java高并发 - 第18天:玩转java线程,这一篇就够了

    摘要:高并发系列第篇文章。简单的说,在使用了线程池之后,创建线程变成了从线程池中获取一个空闲的线程,然后使用,关闭线程变成了将线程归还到线程池。如果调用了线程池的方法,线程池会提前把核心线程都创造好,并启动线程池允许创建的最大线程数。 java高并发系列第18篇文章。 本文主要内容 什么是线程池 线程池实现原理 线程池中常见的各种队列 自定义线程创建的工厂 常见的饱和策略 自定义饱和策略 ...

    AdolphLWQ 评论0 收藏0
  • Java中的线程

    摘要:中的线程池运用场景非常广泛,几乎所有的一步或者并发执行程序都可以使用。代码中如果执行了方法,线程池会提前创建并启动所有核心线程。线程池最大数量线程池允许创建的线程最大数量。被称为是可重用固定线程数的线程池。 Java中的线程池运用场景非常广泛,几乎所有的一步或者并发执行程序都可以使用。那么线程池有什么好处呢,以及他的实现原理是怎么样的呢? 使用线程池的好处 在开发过程中,合理的使用线程...

    tomato 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<