ReentrantLock 与synchronized 区别简要

1.原始构成
synchronized 是关键字,属于jvm层面。
ReentrantLock 是具体类,属于api层面。

2.使用方法
synchronized 不需要手动释放锁,当synchronized 代码执行完后系统会自动让线程释放锁。
ReentrantLock 则需要手动释放锁,就有可能导致死锁。需要lock()和unlock()方法配合try/finally语句块来完成。

3.等待是否可中断
synchronized 不可中断,要么抛出异常,要么正常运行完成。
ReentrantLock 可中断:
1.通过tryLock(Long timeout,TimeUnit unit)设置超时,超时就中断不再等待了。
2.lockInterruptibly()放代码中,通过interrupt()方法可中断。

4.加锁是否公平
synchronized 非公平锁
ReentrantLock 构造方法传入boolean值,true为公平锁,false为非公平锁,默认为公平锁。

5.ReentrantLock 可通过Condition的绑定多个条件,实现精确唤醒。

示例:

/**
 * 多线程之间按顺序调用,实现A->B->C三个线程启动,要求如下: AA打印两次,BB打印三次,CC打印四次 来三轮
 */
public class LockDemo {
  static class ShareData {
    private Lock lock = new ReentrantLock();
    Condition c1 = lock.newCondition();
    Condition c2 = lock.newCondition();
    Condition c3 = lock.newCondition();
    int num = 1;

    public void print2() {
      try {
        lock.lock();
        lock.lockInterruptibly();
        while (num != 1) {
          c1.await();
        }
        for (int i = 0; i < 2; i++) {
          System.out.println("AA");
        }
        num = 2;
        c2.signal();
      } catch (InterruptedException e) {
        e.printStackTrace();
      } finally {
        lock.unlock();
      }
    }

    public void print3() {
      try {
        lock.lock();
        while (num != 2) {
          c2.await();
        }
        for (int i = 0; i < 3; i++) {
          System.out.println("BB");
        }
        num = 3;
        c3.signal();
      } catch (InterruptedException e) {
        e.printStackTrace();
      } finally {
        lock.unlock();
      }
    }

    public void print4() {
      try {
        lock.lock();
        while (num != 3) {
          c3.await();
        }
        for (int i = 0; i < 4; i++) {
          System.out.println("CC");
        }
        num = 1;
        c1.signal();
      } catch (InterruptedException e) {
        e.printStackTrace();
      } finally {
        lock.unlock();
      }
    }
  }

  public static void main(String[] args) {
    ShareData shareData = new ShareData();
    new Thread(() -> {
      for (int i = 0; i < 3; i++) {
        shareData.print2();
      }

    }).start();
    new Thread(() -> {
      for (int i = 0; i < 3; i++) {
        shareData.print3();
      }
    }).start();
    new Thread(() -> {
      for (int i = 0; i < 3; i++) {
        shareData.print4();
      }
    }).start();
  }
}

你可能感兴趣的:(ReentrantLock 与synchronized 区别简要)