Java并发编程学习笔记

线程池

策略

  1. 当线程数量未达到核心线程数量,直接启动一个核心线程来执行任务。
  2. 如果线程数量已达到或者超过核心线程的数量,任务被插入到任务队列中排队执行。
  3. 如果在步骤2中无法将任务插入到任务队列中,这往往是由于任务队列已满,这时候如果线程数量未达到线程池规定的最大值,会立刻启动一个非核心线程来执行任务。
  4. 如果步骤3中线程数量达到最大值,就拒绝执行此任务。

模式
并发编程中经常使用消费者和生产者模式,通过一个容器来解决生产者和消费者的强耦合问题。大多数设计模式都会找出一个第三者进行解耦。

优点

  1. 重用线程池中的线程
  2. 有效控制线程池的最大并发数
  3. 对线程进行有效的管理,并提供定时执行及制定间隔循环执行等功能。

备注
如果已知晓策略,没有必要记优点。因为优点可直接由策略推导出来。

Executor框架

Executor作为用户级的调度器,用于将任务映射为固定数量的线程。Executor框架主要由3大部分组成:

  1. 任务。包括被执行任务需要实现的接口:Runnable或Callable接口。Runnable不返回结果,而Callable返回。
  2. 任务的执行。包括任务执行机制的核心接口Executor,以及继承自Executor的ExecutorService接口。ThreadPoolExecutor及ScheduledThreadPoolExecutor实现了ExecutorService接口。ScheduledThreadPoolExecutor主要用来执行定期或延迟的任务。
  3. 异步计算的结果。包括接口Future和实现Future接口的FutureTask接口。FutureTask是一个可对任务进行状态干预的Runnable异步对象。包括超时处理/取消任务/同步状态等干预。

注意参数
keepAliveTime
线程活动保持时间。线程池中非核心的工作线程空闲后保持存活时间。默认核心线程会在线程池中一直存活,即使处于闲置状态。

线程运行状态变迁

线程运行状态变迁图

(1)BLOCKED(等待获取锁时进入的状态)
synchronized

(2)WAITING(通过wait方法进入的等待)
当wait,join,park方法调用时,进入waiting状态。前提是这个线程已经拥有锁了。进入该状态表示当前线程需要等待其他线程做出一些特定动作(通知或中断)。

blocked和waiting状态的区别是:
A、blocked是虚拟机认为程序还不能进入某个区域,因为同时进去就会有问题,这是一块临界区。
B、发生wait等操作的先决条件是要进入临界区,也就是线程已经拿到锁了,自己可能进去做了一些事情,但此时通过判定业务上的参数,发现还有一些其他配合的资源没有准备充分,那么自己就等等再做其他事情。

(3)TIMED_WAITING(通过sleep或wait timeout方法进入的限期等待的状态)
通过wait(t),sleep(t),join(t),parkNanos,parkUntil等方法进入此状态。当时间达到时触发线程回到工作状态Runnable。

Thread.yield( )方法会将当前线程的可执行时间释放,从运行中的状态变为就绪状态。

Interrupted中断

中断不属于状态,中断可以理解为线程的一个标识位属性,表示一个运行中的线程是否被其他线程进行了中断操作。

在waiting状态下,如果发生了interrupt操作,则处于该状态的线程在内部会抛出一个InterruptedException,这个异常应当在run方法内捕获,使得run方法正常地执行完成,当然捕获异常后,是决定让线程继续运行,还是结束等要根据业务场景才处理。

interrupt只对处于waiting或timed_waiting状态的线程起作用,对其他状态不起作用。

并发/并行/线程/异步

  1. 并行(parallel):在操作系统中,一组程序按独立异步的速度执行,无论从微观还是宏观,程序都是一起执行的。

  2. 并发(concurrent):在操作系统中,是指一个时间段中有几个程序都处于已启动运行到运行完毕之间,且这几个程序都是在同一个处理机上运行,但任一个时刻点上只有一个程序在处理机上运行。其中两种并发关系分别是同步和互斥:

2.1 互斥:进程间相互排斥的使用临界资源的现象,就叫互斥。
2.2 同步:进程之间的关系不是相互排斥临界资源的关系,而是相互依赖的关系。进一步的说明:就是前一个进程的输出作为后一个进程的输入,当第一个进程没有输出时第二个进程必须等待。具有同步关系的一组并发进程相互发送的信息称为消息或事件。

并行的关键是拥有同时处理多个任务的能力。而并行的关键是拥有处理多个任务的能力,不一定要同时。

  1. 线程: 线程本质上是进程中一段并发运行的代码,所以线程需要操作系统投入CPU资源来运行和调度。
    线程都拥有各自的计数器、堆栈和局部变量等属性,并且能够访问共享的内存变量。一个线程在一个时刻只能运行在一个处理器核心上。
    多线程中每个线程的处理程序依然是顺序执行。多线程可以实现线程间的切换执行。

  2. 异步:异步使用回调的方式进行处理。异步是最终目的,多线程只是我们实现异步的一种手段。

  3. 上下文切换:任务从保存到再加载的过程就是一次上下文切换。
    参考

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 记一下学习过程的觉得需要注意的点吧 第二章、线程安全性 无状态对象一定是线程安全的内置锁是可重入的,就是说获得锁的...
    nyle阅读 245评论 0 0
  • layout: posttitle: 《Java并发编程的艺术》笔记categories: Javaexcerpt...
    xiaogmail阅读 5,876评论 1 19
  • 学习资料: Java编程思想 并发,在操作系统中,是指一个时间段中有几个程序都处于已启动运行到运行完毕之间,且这几...
    英勇青铜5阅读 1,419评论 0 4
  • 又到金秋日,回望艳阳天。那时青春年少,不信世事艰。已知山高路远,犹任志满情酣,不肯让人先。谁料枫林晚,徒剩影阑珊。...
    年轻的风阅读 359评论 2 6
  • 怀胎十月的母亲, 用人世间最美好的愿望憧憬着你。 从你瓜瓜坠地的那一刻起, 他们把世间最美好的一切给了你, 不惜生...
    中华复兴阅读 348评论 0 2