Synchronized和ReentrantLock的区别?

324 阅读1分钟

Synchronized & reentrantLock

ps:对比列出不同。

  1. 需要在同步的对象中加入该关键字,可以加在方法上,也可以加在特定代码块上,括号中标识需要锁的对象。
  2. 需要显示指定起始位置和结束位置,加锁以及解锁,lock&unlock。
  3. synchronized:如果异常了,其会自动释放锁,不会出现死锁。
  4. reentrantLock:异常了,不会释放锁,需要手动unlock释放锁。
  5. sync: 可重入,非公平锁。 lock:可重入,既可以公平也可以不公平
  6. 性能:在线程竞争激烈的情况下,lock性能更高。
    • sync是由Jvm实现,底层使用的CPU悲观锁机制,即线程获取的是独占锁。
    • Lock是由java代码控制实现,使用的是乐观锁机制,即CAS操作。
    • sync:少量同步
    • lock:大量同步
  7. 底层实现:
    • sync底层使用指令码的方式来控制锁的,映射成字节码指令就是增加两个命令:monitorEnter,monitorExit,当当前线程遇到enter的时候就去尝试获取内置锁,如果获取锁则锁计数器进行加1,如果exit就进行减1,同一个线程在获取同一把锁的时候可重复获取锁,这就是锁的可重入。
    • lock底层是CAS乐观锁,依赖AQS类,把所有的请求线程构成一个CLH队列,而对该队列的操作都通过CAS操作。

示例:

// sync
private final Object sync = new Object();

public synchronized void sync() {
    System.out.println("You are beautiful,come on!");
}

public void syncS() {
    synchronized (sync) {
        System.out.println("I m get this");
    }
}

// lock
ReentrantLock lock = new ReentrantLock();

public void lock() {
    lock.lock();
    try {
        System.out.println("I love you");
    } finally {
        lock.unlock();
    }
}