|第12章 并发
12.1 什么是线程
- 多线程和写多进程的区别?
- 每个进程拥有一套完成变量,而线程共享数据
- 如何通过Runnable启动线程?
|
|
12.2 线程状态
- 线程的状态有哪些?如何获取?
- New
- Runnable 可运行:start()被调用后。可以正在运行也可以未在运行。
- Blocked 阻塞:要获得一个被其他线程占用的锁
- Waiting:等待某个条件产生的通知
- Timed Waiting 计时等待:Thread.sleep...
- Terminated:退出run()
- 线程状态可通过
Thread.getState()
获取
- 有哪些调度模式?
- 抢占式、协作式(Thread.yield被调用时才失去控制权。相当于宣告暂时离开)
- 如何终止线程?
- 无法强制终止。除非调用已废弃的Thread.stop()。通过
Thread.interrupt()
可请求终止,设置中断标记
- 无法强制终止。除非调用已废弃的Thread.stop()。通过
InterruptedException
何时抛出- 在阻塞/等待的线程调用interrupt()时。不要抑制该异常的抛出!
interrupt()
/isInterrupted()
有何区别?- 前者是静态方法,调用则修改
中断标记
;后者是实例方法,调用不影响线程状态
- 前者是静态方法,调用则修改
setDaemon(boolean isDaemon
的作用?- 在线程开始前设置线程为守护线程(Daemon thread)或用户线程。守护线程允许JVM在程序执行完毕而线程仍在运行时退出。如GC。
12.4 同步
- 什么是
竞态条件(race condition)
- 两个或两个以上线程同时修改一个对象。
- 非原子操作的各个步骤穿插执行的风险很高
- 哪两种机制可以防止并发访问代码块?
synchronized
和ReentrantLock
ReentrantLock
重入锁的工作机制?
|
|
- 何时需要
condition variable
条件对象?怎么用?- 当被重入锁锁定的处理进入临界区,但未达到执行条件时,由于此时别的线程无法访问该对象,执行可能进入死锁。此时调用条件对象暂时放弃锁,等别的线程改变状态可能达到执行条件时的通知,再继续使用锁执行余下操作。
|
|
synchronized
同步方法等价于获取什么锁?内部对象锁
:intrinsicLock
- 用
synchronized
实现条件对象
|
|
- 更应该使用重入锁和同步方法中的哪个?
java.util.concurrent
最优,synchronized次优
- 除了调用同步方法,还有哪种方法可以获得对象的锁?
- 进入
同步块
:
- 进入
|
|
volatile
字段的用处?- 为实例字段的同步访问提供了一种免锁机制,令编译器插入适当代码,使对该字段的修改对读取该字段的所有线程都可见。
- 如何使用线程局部变量避免线程间共享数据?
- 利用
ThreadLocal
辅助类wrap对象
- 利用
|
|
12.5 线程安全的集合
阻塞队列
有哪3类方法?分别有哪些特征?- 作为多线程控制工具:
take
,put
;从空队列取元素和向满队列放元素时阻塞。 - 抛出异常:
add
:添加一个元素。满队列则抛出 IllegalStateExceptionremove
:去除并返回队头元素。空队列则抛出NoSuchElementExceptionelement
:返回队头元素。空队列则抛出NoSuchElementException
- 不抛出异常只返回错误提示:
offer
:添加一个元素并返回true。满队列则返回falsepoll
:去除并返回队头元素。空队列则返回nullpeek
:返回队头元素。空队列则返回null
- 作为多线程控制工具:
阻塞队列
的工作流程
|
|
- 其余内容先看第9章 集合
12.6 任务和线程池
- 如何使用执行器生成线程池?
- 用
Executor
类的静态工厂方法(newFixedThreadPool
等)构造线程池(返回ExecutorService) - 用
submit
方法将Callable
或Runnable
提交给线程池 - 保存返回的Future对象
- 不再提交任务时调用
shutdown
- 用
- 如何不单个提交任务而使用任务组批量处理?
|
|