4、JUC Executors 使用&源码分析

未完待续,写作中…

1、JUC里有几种线程池?各自的使用场景?

FixedThreadPool

public static ExecutorService newFixedThreadPool(int nThreads) {return new ThreadPoolExecutor(nThreads, nThreads,0L, TimeUnit.MILLISECONDS,new LinkedBlockingQueue<Runnable>());
}
public static ExecutorService newFixedThreadPool(int nThreads, ThreadFactory threadFactory) {return new ThreadPoolExecutor(nThreads, nThreads,0L, TimeUnit.MILLISECONDS,new LinkedBlockingQueue<Runnable>(),threadFactory);
}

CachedThreadPool

public static ExecutorService newCachedThreadPool() {return new ThreadPoolExecutor(0, Integer.MAX_VALUE,60L, TimeUnit.SECONDS,new SynchronousQueue<Runnable>());
}
public static ExecutorService newCachedThreadPool(ThreadFactory threadFactory) {return new ThreadPoolExecutor(0, Integer.MAX_VALUE,60L, TimeUnit.SECONDS,new SynchronousQueue<Runnable>(),threadFactory);
}

SingleThreadExecutor

public static ExecutorService newSingleThreadExecutor() {return new FinalizableDelegatedExecutorService(new ThreadPoolExecutor(1, 1,0L, TimeUnit.MILLISECONDS,new LinkedBlockingQueue<Runnable>()));
}
static class FinalizableDelegatedExecutorServiceextends DelegatedExecutorService {FinalizableDelegatedExecutorService(ExecutorService executor) {super(executor);}protected void finalize() {super.shutdown();}
}
4.1、简单使用线程池
public class FixedThreadPoolTest {public static void main(String[] args) {ExecutorService executorService = Executors.newFixedThreadPool(3);for (int i = 0; i<6; i++) {executorService.execute(new Runnable() {public void run() {System.out.println(Thread.currentThread().getName());ThreadUtils.sleep(1000);}});}}
}

ExecutorService executorService = Executors.newFixedThreadPool(3),创建一个拥有 固定数量线程 的线程池。

4.1.1、Executors、ExecutorService命名

我初学JUC 线程池的时候,很不能理解,为什么要用 Executors 这个命名的工具类来创建线程池? 线程池为什么还是ExecutorService 接口的实现类?

不知道大家有没有这个疑惑?

线程池的作用是干嘛的?单纯的线程池没什么意义,执行任务才是线程池存在的意义。所以从执行任务这个角度来看,使用 ExecutorsExectutorService 两个命名就显得合情合理了!!

ThreadPoolExecutor 源码
NO. 项目 二进制
A CAPACITY 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
B ~CAPACITY 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
1 RUNNING(-1) 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
2 SHUTDOWN(0) 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
3 STOP(1) 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
4 TIDYING(2) 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
5 TERMINATED(3) 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
 private static int runStateOf(int c)     { return c & ~CAPACITY; }private static int workerCountOf(int c)  { return c & CAPACITY; }

int的前3位表示 状态,通过与~CAPACITY进行与运算可以取得(~CAPACITY 的前三位为全1)
int的后29位表示 线程数量,通过与CAPACITY进行与运算可以取得(CAPACITY 的后29位为全1)

点击参考:反码 & 为什么使用反码

java.util.concurrent.ThreadPoolExecutor#execute源码:

public void execute(Runnable command) {if (command == null)throw new NullPointerException();int c = ctl.get();if (workerCountOf(c) < corePoolSize) {if (addWorker(command, true))// 新增工作线程return;c = ctl.get();}// 当前 "线程池处于RUNNING状态",则 "添加当前任务到任务队列"if (isRunning(c) && workQueue.offer(commxand)) {int recheck = ctl.get();if (! isRunning(recheck) && remove(command))reject(command);else if (workerCountOf(recheck) == 0)addWorker(null, false); }else if (!addWorker(command, false))reject(command);}
private boolean addWorker(Runnable firstTask, boolean core) {retry:for (;;) {int c = ctl.get();int rs = runStateOf(c);// Check if queue empty only if necessary.if (rs >= SHUTDOWN &&! (rs == SHUTDOWN &&firstTask == null &&! workQueue.isEmpty()))return false;for (;;) {int wc = workerCountOf(c);if (wc >= CAPACITY ||wc >= (core ? corePoolSize : maximumPoolSize))return false;if (compareAndIncrementWorkerCount(c))break retry;c = ctl.get();  // Re-read ctlif (runStateOf(c) != rs)continue retry;// else CAS failed due to workerCount change; retry inner loop}}boolean workerStarted = false;boolean workerAdded = false;Worker w = null;try {w = new Worker(firstTask);final Thread t = w.thread;if (t != null) {final ReentrantLock mainLock = this.mainLock;mainLock.lock();try {// Recheck while holding lock.// Back out on ThreadFactory failure or if// shut down before lock acquired.int rs = runStateOf(ctl.get());if (rs < SHUTDOWN ||(rs == SHUTDOWN && firstTask == null)) {if (t.isAlive()) // precheck that t is startablethrow new IllegalThreadStateException();workers.add(w);int s = workers.size();if (s > largestPoolSize)largestPoolSize = s;workerAdded = true;}} finally {mainLock.unlock();}if (workerAdded) {t.start();workerStarted = true;}}} finally {if (! workerStarted)addWorkerFailed(w);}return workerStarted;
}

⭐️ addWorker(command, true) 上面时候返回 false ?

1、JUC里有几种线程池?各自的使用场景?

1、fixed(固定数量的线程);
使用 固定数量的线程 & 无界队列 来处理你提交的任务,只有指定数量的线程来处理任务。
这些线程都处于运行中时提交任务,任务需要放入无界队列中等待处理。

2 、cached(线程数量不固定,无论来多少任务都是不停的创建线程来执行,如果线程空闲了一定的时间,就会释放掉这个线程);

3 、single(线程池里就只有一个线程)

4、scheduled(提交进去的线程,会在指定的时间过后才去执行)

最最常见的线程池就是fixed线程池,线程数量是固定的,不会超过这个数量的线程,就执行你不断提交的任务

Java线程池(3)- JUC Executors 源码分析相关推荐

  1. java线程池(八):ForkJoinPool源码分析之四(ForkJoinWorkerThread源码)

    文章目录 1.类结构及其成员变量 1.1 类结构和注释 1.2 常量 2.构造函数 2.1 ForkJoinWorkerThread(ForkJoinPool pool) 2.2 ForkJoinWo ...

  2. 一文带你熟透Java线程池的使用及源码

    在单个线程使用过程中遇到的问题(new Thread().start): 线程的频繁创建与销毁 线程执行数据多且高频,频繁CPU上下文切换,造成CPU的资源浪费 以上种种问题,让我们不禁想到,怎么复用 ...

  3. 线程池原理初探以及源码分析(详解)

    1,为什么用线程池 在学java基础的时候,就学过线程的创建方式,如继承Thread类,实现Runnable接口,实现Callable接口这三种,但是在企业级开发中,由于存在多线程以及高并发等现象,如 ...

  4. Java Executor源码解析(3)—ThreadPoolExecutor线程池execute核心方法源码【一万字】

    基于JDK1.8详细介绍了ThreadPoolExecutor线程池的execute方法源码! 上一篇文章中,我们介绍了:Java Executor源码解析(2)-ThreadPoolExecutor ...

  5. mysql 线程池源码模块_易语言Mysql线程池2.0模块源码

    易语言Mysql线程池2.0模块源码 易语言Mysql线程池2.0模块源码 系统结构:GetThis,初始化,关闭类线程,线程_测试,其他_附加文本,连接池初始化,取mysql句柄,释放mysql句柄 ...

  6. Java Review - SimpleDateFormat线程不安全原因的源码分析及解决办法

    文章目录 概述 复现问题 源码分析 How to Fix ? 每次使用时new一个SimpleDateFormat的实例 加锁 使用ThreadLocal 换API - JodaTime or JDK ...

  7. java实现多线程的方式并源码分析

    个人资源与分享网站:首页-小草资源分享网站 方式一:继承Thread 定义一个MyThread类,重写run方法 public class MyThred extends Thread{ @Overr ...

  8. JUC - ReentrantReadWriteLock 源码分析

    简介 ReentrantReadWriteLock,读写锁.维护了一对相关的锁,一个用于只读操作,另一个用于写入操作.只要没有 writer,读取锁可以由多个 reader 线程同时保持.写入锁是独占 ...

  9. java的双亲委派模型-附源码分析

    1.类加载器 1.1 类加载的概念   要了解双亲委派模型,首先我们需要知道java的类加载器.所谓类加载器就是通过一个类的全限定名来获取描述此类的二进制字节流,然后把这个字节流加载到虚拟机中,获取响 ...

最新文章

  1. 关联规则挖掘算法_数据挖掘 | 关联规则分析
  2. 交易系统高并发下的幂等性设计原则
  3. docker 空间满数据迁移笔记
  4. 关于HTML静态页面(含自动分页)生成的可行性方案
  5. 深度Linux对比比,深度Linux10.06 beta1与ylmfOS 3.0简单对比
  6. 【学习OpenCV4】几何图形的绘制方法
  7. mysql 5.5 驱动jar包_MySQL驱动jar包下载
  8. Qt读取海康威视NVR服务器视频
  9. 传输线模型及方程推导
  10. ojdbc连接oracle报错:IO 错误: The Network Adapter could not establish the connection
  11. 京东到家订单订单查询服务演进
  12. MTK样机抓取log
  13. 20210212【学习笔记】Python初步
  14. Flink【优质】面试
  15. KDevelop详细Debug教程
  16. 《从零开始的记账本开发》第2篇 概要设计
  17. 计算机散热程序,电脑的散热方法_百度经验
  18. 随机信号处理笔记 - ING
  19. Creo,SolidWorks,Freecad,QCad,DraftSight,QutoCad
  20. OpenAI 人工智能绘图工具 DALLE 好用吗?

热门文章

  1. windos 为什么会突然服务停止了_女生为什么会突然说分手?
  2. 牛客网训练赛26D(xor)
  3. 玩游戏用什么轴的机械键盘好_机械键盘下的“轴”到底是什么?
  4. SQL 窗口函数的优化和执行
  5. Oracle expdp和impdp
  6. anaconda安装python3.7、jupyter_Anaconda3 Python 3 和 2 in Jupyter Notebook共存方法
  7. append替换代码后jquery不起作用_jQuery部分笔记
  8. 1从控制台输入年份,判断是闰年还是平年;
  9. java精确除法运算-BigDecimal
  10. Java 8 Comparator: 列表排序