互斥:多个线程争抢同一把锁,只有一个线程能够成功
同步:多个线程同时运行,当一个线程运行到某一行代码时,发现需要其他线程的结果,此时该线程就不能继续向下运行了,需要等待其他线程的结果,才能继续向下执行(synchronized可以通过wait,notify实现同步;lock 可以使用条件变量condition.await()释放锁(释放锁之后就进入了等待队列);condition.single()唤醒 (唤醒之后还是会到blocked queue来排队) 来实现同步)
锁重入:持锁的线程能不能继续加第二道锁第三道锁,如果可以则是可重入锁(synchronized,lock 都是可重入锁,对同一个对象加多道锁)
获取等待状态:比如互斥,一个线程获取到锁,其他线程阻塞,此时想知道那些线程被阻塞住了,synchronized 就不行,但是lock就可以;在比如同步时,有多个线程已经在对象上调用了wait()在等等,想知道该对象上有哪些线程在等待,synchronized 就不行,但是lock就可以;
公平锁:多个线程争抢锁,失败的线程在次是先来先得还是允许别插队呢,先来先得则为公平锁,允许插队则是非公平锁;synchronized 只支持非公平锁(并不是根据锁后给等待的线程分配锁的。每次锁被释放后,任何一个线程都有机会竞争到锁。目的就是为了提高执行性能,当然缺点是有可能会产生线程饥饿。)Lock 即支持公平锁又支持非公平锁;公平锁的吞吐量上并不如非公平锁高,一般推荐非公平锁
可打断:有一个持锁线程,我的线程想获取锁时,如果是lock则可以打断;synchronized 不支持打断
可超时:lock支持设置超时时间,如果超时则放弃锁的获取;synchronized 不支持超时
多条件变量:synchronized只有一个等待队列,lock有多个等待队列
TestReentrantLock类中打印的
| Lock ----------------------|
| owner[null] state[0] |
| blocked queue |
| waiting queue [c1] |
| waiting queue [c2] |
|----------------------------|
owner:代表锁的持有者,null表示没有线程持有这把锁,state代表加锁状态,0表示没有人对他加锁,如果有人加锁则加1
blocked queue:如果获取锁失败则进入队列等待;双向链表
waiting queue [c1]:当前线程获取锁之后条件不满足,则先把锁释放开,将锁给别人用,当前线程需要在waiting queue中等待;LOCK.newCondition("c1");来创建waiting queue;单向链表