并发
Java 并发编程 #
本部分主要讨论了Java并发相关的内容。主要分为几大部分:
线程与任务的概念
第一部分主要讨论线程相关的
- 创建
- 生命周期
- 优先级
- 守护线程
- 中断状态
等相关问题,其中以线程的中断状态这一概念最为重要难懂。
第二部分主要讨论了线程
Thread
类提供的相关方法,以及创建线程的惯用法,包括- 线程让步(yield)
- 线程休眠(sleep)
- 加入线程(join)
- 自管理线程- 创建线程的惯用法
- 捕获线程的异常
其中,
join()
方法和sleep()
方法,比较常用。资源访问受限
并发代码比较“危险”的根本原因,就在于不同的线程,操作了同一份数据。这份数据就是“共享资源”。因此,要想并发程序健壮,这份资源的访问必须受到限制,进程们可不能像无事发生一样,任意地去访问它们。
这就是这部分讨论的主题。
这部分由一个经典的 转帐问题切入。引入了Java并发中的一系列同步机制和概念:
讨论了另一种创建线程的方式。以及从执行任务的线程中获取任务执行的结果,便于后续计算。
JUC使用
Callable
和Future
接口完成这些工作。另外,还讨论了
Runnable
和Callable
的结合体——FutureTask
。简单地讨论了死锁出现的可能原因以及避免死锁的方式。
主要讨论了多线程协同的情况下,如何合适地终止任务。
讨论了生产-消费模型,以及使用阻塞队列实现安全生产-消费的原理。
简单介绍了3种阻塞队列:
- ArrayBlockQueue
- LinkedBlockingQueue
- SynchronousQueue
的工作原理以及存取元素的阻塞机制。
这部分介绍Java的线程池“框架”。主要介绍了
ThreadPoolExecutor
的 核心概念,以及线程在线程池中的 执行流程。顺便讨论了如何优雅地关闭线程池。
最后,介绍了一个新的接口
CompletionService
,它利用一个阻塞队列来管理多个任务的返回值。计划执行任务
这部分是Java线程池的延伸,主要讨论了如何让任务有计划地执行。主要使用了
ScheduledExecutorService
,和第8部分一样,分别讨论了 核心概念和 执行流程。最后,讨论了关闭线程池的方法。
重要的并发组件
Java 1.5以后的并发类库新加入了一些用于解决并发问题的新构件,合理地使用这些构件能够帮助我们写出更加简单且健壮的并发程序。本节内容介绍
java.util.concurrent
包中一些具有代表性的构件,包括
TODO:
- AQS
- Fork/Join