当前位置:   article > 正文

线程池相关学习_class workthread extends thread

class workthread extends thread

线程池的创建方式?

Executors.newCachedThreadPool(); 可缓存线程池

Executors.newFixedThreadPool(); 可定长度  限制最大线程数

Executors.newScheduledThreadPool(); 可定时

Executors.newSingleThreadExecutors(); 单例

底层都是基于ThreadPoolExecutor构造函数封装

这以上四种方式都是在我们的jdk中已经封装好了的,但是在实际项目中我们不会去使用。

因为这四种方式存在着一个很大的缺陷,因为它的底层采用的是无界队列缓存我们的任务的,

那么就有可能会发生我们的线程池溢出的情况。

代码演示:

  1. package com.atqiyu.threadpool;
  2. import java.util.concurrent.ExecutorService;
  3. import java.util.concurrent.Executors;
  4. /**
  5. * @author 7575
  6. * @version 1.0
  7. * 我亦无他,唯手熟尔!
  8. */
  9. public class Test05 {
  10. public static void main(String[] args) {
  11. /*ExecutorService executorService = Executors.newCachedThreadPool();
  12. for (int i = 0;i < 10;i++) {
  13. final int finalI = i;
  14. executorService.execute(new Runnable() {
  15. @Override
  16. public void run() {
  17. System.out.println(Thread.currentThread().getName()+","+ finalI);
  18. }
  19. });
  20. }*/
  21. /*ExecutorService executorService = Executors.newFixedThreadPool(2);
  22. for (int i = 0;i < 10;i++) {
  23. final int finalI = i;
  24. executorService.execute(new Runnable() {
  25. @Override
  26. public void run() {
  27. System.out.println(Thread.currentThread().getName()+","+ finalI);
  28. }
  29. });
  30. }*/
  31. ExecutorService executorService = Executors.newSingleThreadExecutor();
  32. for (int i = 0;i < 10;i++) {
  33. final int finalI = i;
  34. executorService.execute(new Runnable() {
  35. @Override
  36. public void run() {
  37. System.out.println(Thread.currentThread().getName()+","+ finalI);
  38. }
  39. });
  40. }
  41. }
  42. }

我们发现线程池并没有得到复用,通过阅读源码可以知道:

核心线程数:0

最大线程数:无限

  1. public static ExecutorService newCachedThreadPool() {
  2. return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
  3. 60L, TimeUnit.SECONDS,
  4. new SynchronousQueue<Runnable>());
  5. }

线程池底层是如何实现复用的?

本质思想:创建一个线程,不会立马停止或者销毁而是一直实现复用。

1.提前创建固定大小的线程一直保持在运行状态;(可能会非常消耗cpu的资源)

2.当需要线程执行任务,将该任务提交缓存在并发队列中;如果缓存队列满了,则会执行拒绝策略;

3.正在运行的线程从并发队列中获取任务从而实现多线程复用问题;

 线程池的核心点:复用机制 --------

1、提前创建好固定的线程一直在运行状态--------死循环实现

  1. package com.atqiyu.threadpool;
  2. /**
  3. * @author 7575
  4. * @version 1.0
  5. * 我亦无他,唯手熟尔!
  6. */
  7. public class Test04 {
  8. public static void main(String[] args) {
  9. new Thread(() -> {
  10. while (true) {
  11. System.out.println("666666");
  12. }
  13. }).start();
  14. }
  15. }

2、提交的线程任务缓存到一个并发队列集合中,交给我们正在运行的线程执行

3、正在运行的线程就从队列中获取该任务执行

java纯手写线程池:

  1. package com.atqiyu.threadpool;
  2. import java.util.ArrayList;
  3. import java.util.List;
  4. import java.util.concurrent.BlockingDeque;
  5. import java.util.concurrent.LinkedBlockingDeque;
  6. /**
  7. * @author 7575
  8. * @version 1.0
  9. * 我亦无他,唯手熟尔!
  10. *
  11. * 线程池核心点:复用机制 ------
  12. * 1.提前创建好固定的线程一直在运行状态------死循环实现
  13. * 2.提交的线程任务缓存到一个并发队列集合中,交给我们正在运行的线程执行
  14. * 3.正在运行的线程就从队列中获取该任务执行
  15. */
  16. public class MyExecutors {
  17. private List<WorkThread> workThreads;
  18. // 缓存我们的线程任务
  19. private BlockingDeque<Runnable> runnableDeque;
  20. private boolean isRun = true;
  21. /**
  22. * 最大线程数
  23. * @param maxThreadCount
  24. */
  25. public MyExecutors(int maxThreadCount,int dequeSize) {
  26. //2.限制队列容量缓存大小
  27. runnableDeque = new LinkedBlockingDeque<>(dequeSize);
  28. //1.提前创建好固定的线程一直在运行状态------死循环实现
  29. workThreads = new ArrayList<>(maxThreadCount);
  30. for (int i=0;i < maxThreadCount;i++) {
  31. // new WorkThread().start();
  32. WorkThread workThread = new WorkThread();
  33. workThreads.add(workThread);
  34. workThread.start();
  35. }
  36. }
  37. /**
  38. * 工作线程
  39. */
  40. class WorkThread extends Thread {
  41. @Override
  42. public void run() {
  43. while (isRun||runnableDeque.size()>0) {
  44. Runnable runnable = runnableDeque.poll();
  45. if ( runnable != null) {
  46. runnable.run();
  47. }
  48. }
  49. }
  50. }
  51. /**
  52. * 缓存线程任务
  53. * @param command
  54. * @return
  55. */
  56. public boolean execute(Runnable command) {
  57. return runnableDeque.offer(command);
  58. }
  59. public static void main(String[] args) {
  60. MyExecutors myExecutors = new MyExecutors(2, 20);
  61. for (int i = 0;i < 10;i++) {
  62. int finalI = i;
  63. myExecutors.execute(new Runnable() {
  64. @Override
  65. public void run() {
  66. System.out.println(Thread.currentThread().getName()+ "," + finalI);
  67. }
  68. });
  69. }
  70. myExecutors.isRun = false;
  71. }
  72. }

本文内容由网友自发贡献,转载请注明出处:【wpsshop博客】
推荐阅读
相关标签
  

闽ICP备14008679号