锁 | Synchronized | lock |
层级 | java关键字,在jvm层面上 | 一个类 |
锁的释放 | 锁中的同步代码块执行完后会释放锁 | 使用try{}catch{}finally{}手动释放 |
锁的获取 | 线程1获取锁之后,线程2会进行等待 | Lock类中有一个tryLock()方法,尝试获取锁,lock锁的线程不一定需要等待 |
锁状态 | 无法判断 | 可以判断 |
锁类型 | 可重入锁、不可中断、非公平锁 | 可重入锁、可判断、非公平锁/公平锁(可以自己设置) |
性能 | 少量同步 | 大量同步 |
1.synchorized是java内置的一个关键字,而lock是一个inteerface接口,lock接口如下
public interface Lock {
void lock();
void lockInterruptibly() throws InterruptedException;
boolean tryLock();
boolean tryLock(long time, TimeUnit unit) throws InterruptedException;
void unlock();
Condition newCondition();
}
2.synchorized会自动释放锁,lock需要手动开启和释放
public class LockTest {
public static void main(String[] args) {
//new Thread( ()->{new Person1().save();},"线程1").start();
new Thread( ()->{new Person2().save();},"线程2").start();
}
}
class Person1{
private int money = 50;
public synchronized void save(){
while (money > 0){
System.out.println(Thread.currentThread().getName()+".."+money--);
}
System.out.println(Thread.currentThread().getName()+"释放synchronized锁");
}
}
class Person2{
private int money = 50;
Lock lock = new ReentrantLock();
public synchronized void save(){
lock.lock();
try{
System.out.println(Thread.currentThread().getName()+"获得lock锁");
while (money > 0){
System.out.println(Thread.currentThread().getName()+".."+money--);
}
}catch(Exception e){
e.printStackTrace();
}finally {
System.out.println(Thread.currentThread().getName()+"释放lock锁");
lock.unlock();
}
}
}
3.Lock可以让等待锁的线程响应中断处理,如tryLock(long time, TimeUnit unit),而synchronized却不行,使用synchronized时,等待的线程会一直等待下去,不能够中断,程序员无法控制;
4.是否知道获取锁
Lock可以通过trylock来知道有没有获取锁,而synchronized不能;
5.Lock的实现类ReentrantReadWriteLock提供了readLock()和writeLock()用来获取读锁和写锁的两个方法,这样多个线程可以进行同时读操作。
6.synchronized使用Object对象本身的wait 、notify、notifyAll调度机制,而Lock可以使用Condition进行线程之间的调度,