先说结论,后面详解
-
synchronized是关键字,Lock是接口; -
synchronized是隐式的加锁,lock是显式的加锁; -
synchronized可以作用于方法上,lock只能作用于方法块; -
synchronized底层采用的是objectMonitor,lock采用的AQS; -
synchronized是阻塞式加锁,lock是非阻塞式加锁支持可中断式加锁,支持超时时间的加锁; -
synchronized在进行加锁解锁时,只有一个同步队列和一个等待队列, lock有一个同步队列,可以有多个等待队列; -
synchronized只支持非公平锁,lock支持非公平锁和公平锁; -
synchronized使用了object类的wait和notify进行等待和唤醒, lock使用了condition接口进行等待和唤醒(await和signal); -
lock支持个性化定制, 使用了模板方法模式,可以自行实现lock方法;
synchronized是关键字,Lock是接口
void lock();
void unlock();
boolean tryLock();
boolean tryLock(long time, TimeUnit unit) throws InterruptedException;
void lockInterruptibly() throws InterruptedException;
Condition newCondition();
synchronized是隐式的加锁,lock是显式的加锁
synchronized可以作用于方法上,lock只能作用于方法块
1.作用于静态方法时,锁的对象是class
2.作用于普通方法是,锁的可以是任意的对象
3.作用于代码块时,反编译后,monitorenter monitorexit exception时的monitorexit
4.作用于方法时,反编译后,方法的flag里面加一个acc_synchronized访问标志
synchronized是阻塞式加锁,lock是非阻塞式加锁支持可中断式加锁,支持超时时间的加锁
tryLock(long time, TimeUnit unit)
lockInterruptibly
synchronized底层采用的是objectMonitor,lock采用的AQS
A,B线程竞争获取锁时,加入B线程未获取到锁,会进入到objectMonitor的entrylist(同步队列)中,获取到锁的线程调用wait后会进入waitset(等待队列)
通过一个int类型的state变量,来判断锁是否被获取,未获取到锁的线程会通过cas加入到双端队列的尾部
synchronized在进行加锁解锁时,只有一个同步队列和一个等待队列, lock有一个同步队列,可以有多个等待队列
synchronized只支持非公平锁,lock支持非公平锁和公平锁
公平锁与非公平锁的区别就在于获取锁的方式不同,公平锁获取,当前线程必须检查sync queue里面是否已经有排队线程。而非公平锁则不用考虑这一点,当前线程可以直接去获取锁。
synchronized使用了object类的wait和notify进行等待和唤醒, lock使用了condition接口进行等待和唤醒(await和signal)
class BoundedBuffer {
final Lock lock = new ReentrantLock();
final Condition notFull = lock.newCondition();
final Condition notEmpty = lock.newCondition();
final Object[] items = new Object[100];
int putptr, takeptr, count;
public void put(Object x) throws InterruptedException {
lock.lock();
try {
while (count == items.length)
notFull.await();
items[putptr] = x;
if (++putptr == items.length) putptr = 0;
++count;
notEmpty.signalAll();
} finally {
lock.unlock();
}
}
public Object take() throws InterruptedException {
lock.lock();
try {
while (count == 0)
notEmpty.await();
Object x = items[takeptr];
if (++takeptr == items.length) takeptr = 0;
--count;
notFull.signalAll();
return x;
} finally {
lock.unlock();
}
}
}
|