线程实现方式

Thread、Runnable、Callable

//实现Runnable接口的类将被Thread执行,表示一个基本任务

public interface Runnable {

//run方法就是它所有内容,就是实际执行的任务

public abstract void run();

}

//Callable同样是任务,与Runnable接口的区别在于它接口泛型,同时它执行任务候带有返回值;

//Callable的使用通过外层封装成Future来使用

public interface Callable {

//相对于run方法,call方法带有返回值

V call() throws Exception;

}

注意:启动Thread线程只能用start(JNI方法)来启动,start方法通知虚拟机,虚拟机通过调用器映射到底层操作系统,通过操作系统来创建线程来执行当前任务的run方法

Executor框架

Executor接口是线程池框架中最基础的部分,定义了一个用于执行Runnable的execute方法。从图中可以看出Exectuor下有一个重要的子接口ExecutorService,其中定义了线程池的具体行为:

execute(Runnable runnable):执行Runnable类型的任务

submit(task):用来提交Callable或者Runnable任务,并返回代表此任务的Future对象

shutdown():在完成已经提交的任务后封闭办事,不在接管新的任务

shutdownNow():停止所有正在履行的任务并封闭办事

isTerminated():是一个钩子函数,测试是否所有任务都履行完毕了

isShutdown():是一个钩子函数,测试是否该ExecutorService是否被关闭

ExecutorService中的重点属性:

private final AtomicInteger ctl = new AtomicInteger(ctlOf(RUNNING, 0));

private static final int COUNT_BITS = Integer.SIZE - 3;

private static final int CAPACITY = (1 << COUNT_BITS) - 1;

ctl:对线程池的运行状态和线程池中有效线程的数量进行控制的一个字段,它包含两部分信息:线程池的运行状态(runState)和线程池内有效线程的数量(workerCount)。

这里可以看到,使用Integer类型来保存,高3位保存runState,低29位保存workerCount。COUNT_BITS 就是29,CAPACITY 就是1左移29位减1(29个1),这个常量表示workerCount的上限值,大约是5亿。

ctl相关方法:

//获取运行状态

private static int runStateOf(int c){

return c & ~CAPACITY;

}

//获取活动线程数

private static int workerCountOf(int c) {

return c & CAPACITY;

}

//获取运行状态和活动线程数的值

private static int ctlOf(int rs, int wc) {

return rs | wc;

}

线程池的状态:

RUNNING = -1 << COUNT_BITS; //高3位为111

SHUTDOWN = 0 << COUNT_BITS; //高3位为000

STOP = 1 << COUNT_BITS; //高3位为001

TIDYING = 2 << COUNT_BITS; //高3位为010

TERMINATED = 3 << COUNT_BITS; //高3位为011

线程池实例的状态

1、RUNNING

状态说明:线程池处于RUNNING状态,能够接收新任务,以及对已添加的任务进行处理。

状态切换:线程池的初始化状态是RUNNING。换句话说,线程池一旦被创建,就处于RUNNING状态,并且线程池中的任务数为0。

2、SHUTDOWN

状态说明:线程池处于SHUTDOWN状态,不接收新任务,能够处理已经添加的任务。

状态切换:调用shutdown()方法时,线程池由RUNNING -> SHUTDOWN。

3、STOP

状态说明:线程池处于STOP状态,不接收新任务,不处理已提交的任务,并且会中断正在处理的任务。

状态切换:调用线程池中的shutdownNow()方法时,线程池由(RUNNING or SHUTDOWN) -> STOP。

4、TIDYING

状态说明:当所有的任务已经停止,ctl记录“任务数量”为0,线程池会变为TIDYING状态。当线程池处于TIDYING状态时,会执行钩子函数 terminated()。terminated()在ThreadPoolExecutor类中是空, 的,若用户想在线程池变为TIDYING时,进行相应处理,可以通过重载 terminated()函数来实现。

状态切换:当线程池在SHUTDOWN状态下,阻塞队列为空并且线程池中执行任务也为空时,就会由SHUTDOWN -> TIDYING。当线程池在STOP状态下,线程池中执行的任务为空时,就会由STOP-> TIDYING。

5、TERMINATED

状态说明:线程池线程池彻底停止,线程池处于TERMINATED状态,

状态切换:线程池处于TIDYING状态时,执行完terminated()之后, 就会由TIDYING->TERMINATED。

线程池使用

ThreadPoolExecutor构造方法

public ThreadPoolExecutor(int corePoolSize,

int maximumPoolSize,

long keepAliveTime,

TimeUnit unit,

BlockingQueue workQueue,

ThreadFactory threadFactory,

RejectedExecutionHandler handler) {

if (corePoolSize < 0 ||

maximumPoolSize <= 0 ||

maximumPoolSize < corePoolSize ||

keepAliveTime < 0)

throw new IllegalArgumentException();

if (workQueue == null || threadFactory == null || handler == null)

throw new NullPointerException();

this.corePoolSize = corePoolSize;

this.maximumPoolSize = maximumPoolSize;

this.workQueue = workQueue;

this.keepAliveTime = unit.toNanos(keepAliveTime);

this.threadFactory = threadFactory;

this.handler = handler;

}

任务的提交流程

执行图:

java 单线程执行器_Java基础-并发编程-线程执行器executor相关推荐

  1. java单线程循环调度_Java基础篇之Java线程模型

    原标题:Java基础篇之Java线程模型 Java运行系统在很多方面依赖于线程,所有的类库设计都考虑到多线程.实际上,Java使用线程来使整个环境异步.这有利于通过防止CPU循环的浪费来减少无效部分. ...

  2. 判断线程是否执行完毕_Java并发编程 | 线程核心机制,基础概念扩展

    源码地址:GitHub || GitEE 一.线程基本机制 1.概念描述 并发编程的特点是:可以将程序划分为多个分离且独立运行的任务,通过线程来驱动这些独立的任务执行,从而提升整体的效率.下面提供一个 ...

  3. Java零基础并发编程入门

    Java零基础并发编程入门 并发编程主要包括: 线程,同步,future,锁,fork/join, volatile,信号量,cas(原子性,可见性,顺序一致性),临界性,分布式 了解基础: JMM: ...

  4. Java 并发编程 -- 线程池源码实战

    一.概述 小编在网上看了好多的关于线程池原理.源码分析相关的文章,但是说实话,没有一篇让我觉得读完之后豁然开朗,完完全全的明白线程池,要么写的太简单,只写了一点皮毛,要么就是是晦涩难懂,看完之后几乎都 ...

  5. 高并发编程-线程通信_使用wait和notify进行线程间的通信2_多生产者多消费者导致程序假死原因分析

    文章目录 概述 jstack或者可视化工具检测是否死锁(没有) 原因分析 概述 高并发编程-线程通信_使用wait和notify进行线程间的通信 - 遗留问题 我们看到了 应用卡住了 .... 怀疑是 ...

  6. python 线程同步_Python并发编程-线程同步(线程安全)

    Python并发编程-线程同步(线程安全) 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 线程同步,线程间协调,通过某种技术,让一个线程访问某些数据时,其它线程不能访问这些数据,直 ...

  7. 并发编程——线程协作

    并发编程--线程协作 ​ 前面学习了线程,那么并发编程中,如何协调多个线程来开发呢? Semaphore ​ 信号量跟前面将的同步互斥解决方案--信号量是一个东西,这是JDK的信号量实现. 源码分析 ...

  8. java线程池_Java 并发编程 线程池源码实战

    作者 | 马启航 杏仁后端工程师.「我头发还多,你们呢?」 一.概述 笔者在网上看了好多的关于线程池原理.源码分析相关的文章,但是说实话,没有一篇让我觉得读完之后豁然开朗,完完全全的明白线程池,要么写 ...

  9. Java并发编程-线程安全基础

    线程安全基础 1.线程安全问题 2.账户取款案例 3.同步代码块synchronized synchronized的理解 java中有三大变量的线程安全问题 在实例方法上使用synchronized ...

最新文章

  1. ORM 框架中SQLALCHEMY一点点个人总结
  2. 一些很实用且必用的小脚本代码:
  3. 实战总结:我是怎么从0到1做后台业务系统的?
  4. 程序员终身发展规划---应对中国软件发展的大环境要求
  5. 九十、深入弹性(Flex)布局
  6. 云盒子企业网盘入驻阿里云市场,正式向公有云市场发力!
  7. Magento教程 1:免费购物车系统,轻松建立Magento第一步!
  8. 用provide/inject来实现简单的vuex状态管理功能
  9. uwp post php,window_Win10开发系列专题五 UWP应用添加画布及语音输入支持,这是微软Win10十个开发系列专 - phpStudy...
  10. java面向对象编程 漫画_Java面向对象编程(一)
  11. Office LTSC 2021 for Mac
  12. 远程控制软件teamview好用么?
  13. pdf转dwg为什么乱码
  14. mac jenkins下载与安装
  15. 学生总分排名的c语言程序,学生成绩分析及排名系统C语言程序设计课程设计实习报告.doc...
  16. 中科院信工所雏鹰团队在SemEval上大显神威
  17. 数据错误循环冗余检查是什么意思_德尔西曼.交换机是一种什么设备?通过什么方式进行交换?...
  18. 佳能数码相机照片删除了怎么恢复,如何恢复还原佳能相机误删的照片
  19. 小满网络模型http1-http2 浏览器缓存
  20. 用VS软件开发“中国象棋“游戏

热门文章

  1. 软考 - 06 在线订餐管理系统
  2. 408数据结构综合题
  3. SDIO wifi Marvell8801/Marvell88w8801 介绍(八) ---- Marvell 8801实现STA功能/连接open热点/连接wpa热点/连接wpa2热点
  4. Qt程序单元测试学习记录
  5. C++项目实现多国语言解决方案
  6. bat脚本:快速入门
  7. 三星SAMSUNG SL-M2676N 驱动
  8. 手撕SVM公式——硬间隔、软间隔、核技巧
  9. 将ios内的文件导入mac
  10. 最新计算机专业毕业设计选题 - 选题推荐