10.3 Locks and Synchronization locking and synchronization
§ 1.Synchronization
§ 2.Locking
§ 3.Atomic operations
§ 4.Liveness: deadlock, starvation and livelock
§ 5.wait(), notify(), and notifyAll()
1.Synchronization synchronization
Use the lock mechanism, mutation obtain exclusive rights to data, other threads are blocked and may not access
Two operating locks: acquire (the one thread to obtain ownership of the lock); release (release the lock of the right to use)
2 Locking
①Lock is embedded mechanism provided by the Java language
Methods: get a piece of code lock through the synchronized statement
Has exclusive lock threads can execute that part of the code, Lock protect shared data
②Monitor make their own lock mode --ADT
An easy way to have any assurance lock, any methods are mutually exclusive, it will only be allowed to call a class method
method:
1) synchronized (this) to ensure that all the classes have been rep lock, the whole body is the method comprising
2) The method of adding the former synchronized
PS: synchronized allowed before the constructor, to ensure that each new JAVA internal operations are atoms
The best Do not use synchronized, synchronization mechanisms have a tremendous impact on performance
PS: Before home synchronized static method is equivalent to the entire class lock, bring great loss of performance
③ operation on the same mutable objects must be protected at all synchronized with each thread, any shared mutable variables must be protected lock
④happens before relations (in principle reordering optimization)
To ensure the implementation of the results of the previous operations must be visible after an operation, to ensure consistency of memory
Definition: as part of the rule
1) the program sequence rules: each operation a thread happens-before any subsequent operation to the thread
2) for unlocking a monitor, happens-before subsequent locking of the monitor
3 Atomic operations atomic
利用关键字volatile减少内存不一致发生的风险。
volatile变量所有的写操作都和随后的操作保证了一个happens-before的关系
这意味着对volatile变量的改变总是对其他变量可见的
volatile不能解决所有问题
synchronized相当于把多个atomic operations 组合成更大的amomic operations
4 Liveness: deadlock, starvation and livelock活性:死锁,饥饿,活锁
(1)Dead lock
死锁:多个线程竞争 lock,相互等待对方释放lock(程序就卡死在这里了)
死锁的特征是循环依赖,都在等对方
死锁发生在一个线程拥有多个锁的时候
解决方法:
1) lock ordering给锁排序
PS:首先这不是模块化的,我们需要知道所有的锁;其次对于代码很难知道哪个锁是先被使用的,需要一些计算
2 ) coarse-grained locking就用一个锁(对性能是很大的影响)
(2)starvation饥饿
因为其他线程 lock 时间太长,一个线程长时间无法获取其所需的资源访问权 (lock) ,导致无法往下进行
(3) Livelock活锁
1)一个线程等待另一个线程回复,另一个线程又等待下一个线程回复,活锁就产生了
2)活锁也会导致线程无法进行,只是不是被阻塞了而是忙于回复对方从而继续工作。
5 wait(),notify(),and notifyAll()
(1)
保护块:某些条件未得到满足,所以一直在空循环检测,直到条件被满足。这是极大浪费。
对于任意的类o,
o.wait():释放o的lock,进入o的等待队列,等待
o.notify():在o 的等待队列中唤醒一个线程
o.notifyAll():唤醒o的等待队列中的所有线程
(2)o.wait()
该操作使object所处的当前线程进入阻塞/等待状态,直到其他线程调用该对象的notify()操作
o.notify()/notifyAll()
随机选择一个在该对象上调用wait方法的线程,解除其阻塞状态
PS:这些方法必须在o被lock的时候调用,如下
(3)锁,同步与这些方法之间的关系