软构期末复习7.1
进程:拥有整台计算机的资源
多进程之间不共享内存,进程之间通过消息传递进行协作;
一般来说,进程 == 程序 == 应用;
但一个应用中可以包含多个进程
线程:
进程=虚拟机,线程=虚拟CPU
程序共享、资源共享都属于进程;
共享内存很难获得线程私有的内存空间,通过创建消息队列在线程之间进行消息传递;
每个应用至少有一个线程;
主线程可以创建其他的线程;
时间分片:
即使有多线程,但只有一个核,每个时刻只能执行一个线程;
通过时间分片,在多个进程/线程间共享处理器;
即使是多核CPU,进程/线程的数目也往往大于核的数目
Thread.sleep() 线程的休眠:
将某个线程休眠,意味着其他线程得到更多的执行机会;
进入休眠的线程不会失去对现有monitor或锁的所有权
Thread.interrupt() 线程中断:
t.interrupt() 在其他线程里向t发出中断信号;
t.isInterrupted() 检查t是否已在中断状态;
一般来说,线程在收到中断信号时应该中断,直接终止
Thread Safety 线程安全:
线程间的“竞争条件”:
作用于同一个mutable数据上的多个线程,彼此间存在对该数据的访问竞争并导致interleaving,导致post-condition可能被违反,这不安全。
线程安全:ADT或方法在多线程中要执行正确
- 不违反spec,保持RI
- 与多少处理器、OS如何调度线程均无关
- 不需要在spec中强制要求client满足某种“线程安全”的义务
线程安全threadsafe的四种策略:
- Confinement 限制数据共享:
将可变数据限制在单一线程内部,避免竞争;
不允许任何线程直接读写该数据;
线程之间不共享mutable数据类型 - Immutability 共享不可变数据:
使用不可变数据类型和不可变引用,避免多线程间的race condition;
不可变数据通常是线程安全的;
如果ADT中使用了beneficent mutation,必须要通过“加锁”机制保证线程安全 - ThreadSafe 共享线程安全的可变数据:
如果必须要用mutable的数据类型在多线程之间共享数据,要使用线程安全的数据类型;
一般来说,JDK同时提供两个相同功能的类,一个是threadsafe,另一个不是。 - Synchronization/Lock 同步机制:通过锁的机制共享线程不安全的可变数据,变并行为串行