当前位置:   article > 正文

Java并发线程池底层原理详解与源码分析_newcachedthreadpool源码

newcachedthreadpool源码

1.线程池与线程性能对比

在单线程情况下处理任务的速度和用线程池对比性能有很大提升,线程池内部可以线程复用,在线程处理完任务以后可以回到线程池,处理其他任务,这样大大减少了线程销毁和创建的时间。

java自带的几种线程池:

ExecutorService executorService = Executors.newCachedThreadPool();
ExecutorService executorService1 = Executors.newFixedThreadPool(100);
ExecutorService executorService2 = Executors.newSingleThreadExecutor();
ExecutorService executorService3 = Executors.newScheduledThreadPool(10);

上面的线程池看构造参数都是用ThreadPoolExecutor创建,只是使用的参数不同。

newCachedThreadPool使用的构造方法:对应参数(核心线程数,最大线程数,线程存活时间,线程存活时间单位,队列),newCachedThreadPool只有0个核心线程,临时线程数可以无限大,所以它的执行效率很高,SynchronousQueue是一个典型的生产者消费者模式,相当于一个外包公司。

new ThreadPoolExecutor(0, Integer.MAX_VALUE,
                              60L, TimeUnit.SECONDS,
                              new SynchronousQueue<Runnable>())
newCachedThreadPool使用的构造方法:核心线程数和临时线程数都是自定义的,LinkedBlockingQueue队列是一个无界阻塞队列,相当于可以无限等待任务处理,但是效率很低。相当于一个国企。
new ThreadPoolExecutor(nThreads, nThreads,
                              0L, TimeUnit.MILLISECONDS,
                              new LinkedBlockingQueue<Runnable>())
newSingleThreadExecutor使用的构造方法:核心线程数和临时线程数都是1,相当于1个人处理无数的任务,效率在很快能处理完任务的时候很快,但是在需要处理任务很慢的时候就会显得效率很低。相当于一个私企,什么都是一个人干。
new FinalizableDelegatedExecutorService
    (new ThreadPoolExecutor(1, 1,
                            0L, TimeUnit.MILLISECONDS,
                            new LinkedBlockingQueue<Runnable>()))

最有可能出现OOM的线程池:newCachedThreadPool,里面不是无界队列,达到内存的最大值后会报OOM情况

前面三种情况阿里规范都不推荐,但在不是能达到内存top值的业务中上面三种都可以用,阿里推荐自定义线程池ThreadPoolExecutor

 1.1 线程池对比实战

  1. import java.util.concurrent.ExecutorService;
  2. import java.util.concurrent.Executors;
  3. public class ThreadDemo {
  4. public static void main(String[] args) {
  5. //定义3个线程池
  6. ExecutorService executorService = Executors.newCachedThreadPool();//很快
  7. ExecutorService executorService1 = Executors.newFixedThreadPool(100);//不快不慢
  8. ExecutorService executorService2 = Executors.newSingleThreadExecutor();//最慢
  9. //定义100个任务给线程池处理对比处理性能
  10. long begin = System.currentTimeMillis();
  11. for(int i=0;i<100;i++){
  12. executorService2.submit(new Task());
  13. }
  14. executorService.shutdown();
  15. long end = System.currentTimeMillis();
  16. System.out.println("处理时间:"+(end-begin)/1000+"秒");
  17. }
  18. }
  19. class Task implements Runnable{
  20. @Override
  21. public void run() {
  22. System.out.println(Thread.currentThread().getName()+"处理完任务");
  23. try {
  24. Thread.sleep(3000);
  25. } catch (InterruptedException e) {
  26. e.printStackTrace();
  27. }
  28. }
  29. }

1.2 ThreadPoolExecutor实战

  1. /**
  2. * 第31个任务会拒绝任务
  3. */
  4. public class ThreadDemo {
  5. public static void main(String[] args) {
  6. //定义ThreadPoolExecutor
  7. ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(10, 30, 0, TimeUnit.SECONDS,
  8. new LinkedBlockingQueue<>(10));
  9. //定义100个任务给线程池处理对比处理性能
  10. long begin = System.currentTimeMillis();
  11. for(int i=0;i<100;i++){
  12. threadPoolExecutor.submit(new Task());
  13. }
  14. threadPoolExecutor.shutdown();
  15. long end = System.currentTimeMillis();
  16. System.out.println("处理时间:"+(end-begin)/1000+"秒");
  17. }
  18. }
  19. class Task implements Runnable{
  20. @Override
  21. public void run() {
  22. System.out.println(Thread.currentThread().getName()+"处理完任务");
  23. try {
  24. Thread.sleep(3000);
  25. } catch (InterruptedException e) {
  26. e.printStackTrace();
  27. }
  28. }
  29. }

1.3 面试题1:自定义线程池参数

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

corePoolSize:核心线程数

int maximumPoolSize:最大线程数

long keepAliveTime:临时线程存活时间

TimeUnit unit:临时线程存活单位

BlockingQueue<Runnable> workQueue:任务队列

ThreadFactory threadFactory:一般自定义工厂类

RejectedExecutionHandler handler:拒绝策略,定义的有4种,一般我们可以自定义拒绝策略

AbortPolicy:默认抛出RejectedExecutionException拒绝任务
DiscardPolicy:抛弃任务
DiscardOldestPolicy:通过队列结构抛出最老的任务
CallerRunsPolicy:由调用execute方法的线程执行任务

1.4 面试题线程池源码分析执行原理图(TODO) 

1.5 面试题submit()与execute方法区别(TODO)

submit与execute的区别:在线程中存在一个提交优先级和执行优先级的概念,提交优先级高于执行优先级。
1. execute方法在submit方法中。
2. submit方法会返回Future泛型函数,而execute不返回

 

 

1.6 面试题offer()与add()区别

add和offer都是任务队列添加任务的方法,区别add方法不抛出异常,而offer会抛出中断异常,这是他们唯一的区别。

 

 

1.7 newScheduledThreadPool(TODO)

1.7.1 newScheduledThreadPool实战(TODO)

1.7.2 源码分析(TODO)

1.8 自定义拒绝策略

自定义拒绝策略两种方法:

//自定义拒绝策略
RejectedExecutionHandler rejectedExecutionHandler = new RejectedExecutionHandler() {
    @Override
    public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) {
        System.out.println("自定义拒绝策略,可以存入数据库");
    }
};

第二种:实现RejectedExecutionHandler接口重写rejectedExecution方法。

  1. import java.util.concurrent.*;
  2. /**
  3. * 第31个任务会拒绝任务
  4. */
  5. public class ThreadDemo {
  6. public static void main(String[] args) {
  7. //自定义拒绝策略
  8. RejectedExecutionHandler rejectedExecutionHandler = new RejectedExecutionHandler() {
  9. @Override
  10. public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) {
  11. System.out.println("自定义拒绝策略,可以存入数据库");
  12. }
  13. };
  14. //定义ThreadPoolExecutor
  15. ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(10, 30, 0, TimeUnit.SECONDS,
  16. new LinkedBlockingQueue<>(10),rejectedExecutionHandler);
  17. //定义100个任务给线程池处理对比处理性能
  18. long begin = System.currentTimeMillis();
  19. for(int i=0;i<100;i++){
  20. threadPoolExecutor.submit(new Task());
  21. }
  22. threadPoolExecutor.shutdown();
  23. long end = System.currentTimeMillis();
  24. System.out.println("处理时间:"+(end-begin)/1000+"秒");
  25. }
  26. }
  27. class Task implements Runnable{
  28. @Override
  29. public void run() {
  30. System.out.println(Thread.currentThread().getName()+"处理完任务");
  31. try {
  32. Thread.sleep(3000);
  33. } catch (InterruptedException e) {
  34. e.printStackTrace();
  35. }
  36. }
  37. }

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/凡人多烦事01/article/detail/246534
推荐阅读
相关标签
  

闽ICP备14008679号