JAVA 多线程同步与互斥
1. 为什么需要互斥:
互斥操作 保证了 多线程操作的 原子性 , java的 互斥 语义 有 synchronized 关键字 提供. 主要方式 有 同步代码块 和 同步方法 两种 |
2. 整数自增操作
常见的线程安全问题:
像这种不是一条指令就能完成的操作 ,并且 有多个线程操作统一资源的时候 ,要保证 上面 三步操作一次执行完,而不被其他线程干扰(原子性:要么 都不执行 ,要么 全部执行) |
3. 线程的等待
Thread.join() ;: java 中的 主线程 默认会 等待 其他线程的 结束 start() 的 作用是 启动 一个线程, 使得 调用处 的线程 流程 一分为二 而join() 方法 则 相反 ,.使得 两个执行流程 合二为一 |
4. 同步
同步就是 要保证 两个线程事件 执行的 时序关系 支持“同步”操作的调用叫做“同步原语”,包括:互斥、条件变量、信号量、信箱、事件标志和Spinlock等
|
5. 信号丢失
wait/notify/notifyAll提供了一种线程间事件通知的方式,但这种通知并不能被有效的“记住”;所以,就存在通知丢失(notify missing)的可能——发出通知的线程先notify,接收通知的线程后wait,此时这个事先发出的通知就会丢失。在POSIX规范上,叫做信号丢失;由于现在的多数操作系统(LINUX,Mac,Unix)都遵循POSIX;所以“信号丢失”这个词使用的更广泛。 |
6. 虚假唤醒
虚假唤醒(spurious wakeup)在采用条件等待时,我们使用的是 while(条件不满足){ condition_wait(cond, mutex); } 而不是: If( 条件不满足 ){ Condition_wait(cond,mutex); } 这是因为可能会存在虚假唤醒”spurious wakeup”的情况。 |