java本身支持synchronize
关键字来进行线程同步,并且在Object根对象中添加了wait() /notify()/notifyAll()
等方法,来实现有条件唤醒。
synchronize
底层实际维护了两个队列,一个是竞争锁的队列,一个是等待唤醒的队列;synchronize
关键字会使当前线程进入竞争锁队列,wait()
会使当前线程进入等待唤醒队列,
Notify()
会唤醒最先进入队列的线程,notifyAll()
会按照LIFO依次唤醒等待线程;
JDK提供了强大的并法包工具类,提供了丰富的API来满足各种并发场景,Condition可以更加的灵活创建多个等待唤醒队列。
需要重点掌握的类如下
- Lock
- LockSupport
- Condition
- ReentrantLock
- ReadWriteLock
- ReentrantReadWriteLock
- BlockingQueue
- LinkedBlockingQueue
- ArrayBlockingQueue
- SynchronousQueue
- CocurrentHashMap
- CopyOnWriteArrayList
- CountDownLatch
- CyclicBarrier
- Future
- FutureTask
- ForkJoinPool
Lock
类定义
public interface Lock{
// 进入竞争锁的队列,如果无法获取锁则当前线程进入
void lock();
// 进入竞争锁的队列,可以被其他线程中断 thread.interrupt()
void lockInterruptibly() throws InterruptedException;
//尝试获取锁,立即返回
boolean tryLock();
// 尝试在指定的时间内获取锁,超时后返回false
boolean tryLock(long time, TimeUnit unit) throws InterruptedException;
//释放所会检查是否当前线程有权限释放,否则抛出异常
void unlock();
// 只有获取锁的线程,才有资格获取condition然后进入condition条件队列
Condition newCondition();
}
Condition
image.pngcondition 是由生产消费者模型启发而来,之前synchronize里的wait、notify不支持多个等待队列,无法对这种模型做优化。
wait() 提供了带时间的方法,由于平台限制,会有surpurise wake up
,带时间的方法返回都提供了是否还有剩余等待时间的线索。
LockSupport
image.png- LockSupport 是生产高级锁的底层工具
- LockSupport 类似于Semaphore,但是只有一个令牌,令牌可以被持有。
- 推荐使用带Object(blocker)的方法,可以用于监控线程为何被park
网友评论