Synchronized与ReentrantLock区别

2020-04-22  本文已影响0人  请不要问我是谁

API层面

这两种方式最大区别就是对于Synchronized来说,它是java语言的关键字,是原生语法层面的互斥,需要jvm实现。而ReentrantLock它是JDK 1.5之后提供的API层面的互斥锁,底层借助AQS实现,需要lock()和unlock()方法配合try/finally语句块来完成。

synchronized既可以修饰方法,也可以修饰代码块。

//synchronized修饰一个方法时,这个方法叫同步方法。
public synchronized void test() {
//方法体``

}

synchronized(Object) {
//括号中表示需要锁的对象.
//线程执行的时候会对Object上锁
}

ReentrantLock使用

private ReentrantLock lock = new ReentrantLock();
public void run() {
    lock.lock();
    try{
        for(int i=0;i<5;i++){
            System.out.println(Thread.currentThread().getName()+":"+i);
        }
    }finally{
        lock.unlock();
    }
}

等待可中断

使用synchronized。如果Thread1不释放,Thread2将一直等待,不能被中断。synchronized也可以说是Java提供的原子性内置锁机制。内部锁扮演了互斥锁(mutual exclusion lock ,mutex)的角色,一个线程引用锁的时候,别的线程阻塞等待。

synchronized执行时如果抛出异常交给jvm处理,会释放锁,因此碰到异常时要小心处理。

使用ReentrantLock。如果Thread1不释放,Thread2等待了很长时间以后,可以中断等待,转而去做别的事情。
void lockInterruptibly() throws InterruptedException;

公平锁

synchronized的锁是非公平锁,ReentrantLock默认情况下也是非公平锁,但可以通过带布尔值的构造函数要求使用公平锁。

ReentrantLock 构造器的一个参数是boolean值,它允许您选择想要一个公平(fair)锁,还是一个不公平(unfair)锁。公平锁:使线程按照请求锁的顺序依次获得锁, 效率比非公平锁低。

锁绑定多个条件

ReentrantLock可以同时绑定多个Condition对象,只需多次调用newCondition方法即可。

synchronized中,锁对象的wait()和notify()或notifyAll()方法可以实现一个隐含的条件。但如果要和多于一个的条件关联的时候,就不得不额外添加一个锁。

ReentrantLock更灵活

可以设置尝试获取锁的时间:
boolean tryLock(long time, TimeUnit unit) throws InterruptedException;

上一篇下一篇

猜你喜欢

热点阅读