锁与同步
- 同步synchronized用来修饰方法,lock是一个实例变量,通过调用lock()方法来取得锁
- 同步和锁都是针对方法,不是同步变量和类
- 同步无法保证线程取得方法执行的先后顺序,锁可以设置公平锁来确保
- 不必同步类中的所有方法,类可以同时拥有同步和非同步方法
- 如果线程拥有同步和非同步方法,则非同步方法和同步方法被多个线程自由访问而不受锁的限制
- 线程睡眠时,持有的锁不会被释放
- 线程可以获得多个锁,比如在一个对象的同步方法里面调用另一个对象的同步方法,则获取了两个对象的锁。
- 同步损害并发性,应该尽可能缩小同步的范围,同步不但可以同步整个方法,还可以同步方法中的一部分代码
- 在使用同步代码块的时候,应该指定在哪个对象上同步,也就是要获得哪个对象的锁
锁的实例
|
|
Lock接口
|
|
ReentrantLock重入锁
成员变量
|
|
只有一个成员变量sync,其抽象类如下
|
|
构造函数
|
|
lock方法
|
|
lockInterruptibly方法
|
|
非公平锁的实现
|
|
tryLock方法
|
|
其中getState获取state的值,0表示未获取到锁,1表示已经获取到锁,大于1表示重入数
tryLock(long timeout, TimeUnit unit)方法
|
|
该方法实际上调用的是Sync父类AbstractQueuedSynchronizer的方法:
|
|
ReadWrite读写锁
- 读写锁的使用场景
- 多线程同时读取临界值,单一线程写
- 阻塞同时读写
读 | 写 | |
---|---|---|
读 | 非阻塞 | 阻塞 |
写 | 阻塞 | 阻塞 |
实例
- 提交18个读任务,2个写任务,使用重入锁耗时奖金20毫秒,使用读写锁耗时3秒左右
|
|
源码解读
ReadWriteLock接口
|
|
ReentrantReadWriteLock类
成员变量
|
|
构造函数
|
|
ReadLock内部类
|
|
WriteLock内部类
|
|
CountDownLatch
- 倒计数器,控制线程等待,直到倒计数器为0,线程继续开始执行。
实例
- 火箭发射中需要进行各个仪器的检查,只有所有的都正常,才可以发射
|
|
- 赛跑或者赛车问题
|
|
CyclicBarrier
- 可以实现线程之间的等待,可以循环使用,如十个一组执行的场景
|
|
LockSupport
- LockSupport类似于suspend(),可以让一个线程在任意位置阻塞,不用获取锁,也不会抛出异常
- park方法阻塞当前线程
|
|