实战小知识----02.04----浅谈Synchronized和Lock

89 阅读2分钟

这是我参与2022首次更文挑战的第12天,活动详情查看:2022首次更文挑战

Synchronized和Lock

Synchronized修饰方法的话,其他同步阻塞的方法,就必须等待该方法的synchronized区域结束释放锁,才能执行。

  • 特性

    • synchronized是Java的内置关键字
    • Lock是一个接口类,在JDK1.5之后出现
      • lock();
      • lockInterruptibly() throws InterruptedException;
      • boolean tryLock();
      • boolean tryLock(long time, TimeUnit unit) throws InterruptedException;
      • void unLock();
      • Condition newCondition();
  • 公平性

    • synchronized是非公平的,也就是不遵循线程访问资源的顺序,这也就有可能导致某些线程永远获取不到资源
    • Lock是公平的,遵循线程访问资源的顺序
  • 乐悲观

    • Synchronized是基于CPU的悲观锁,在获取了资源后,其他的同步方法就只能阻塞等待,直至synchronized方法结束,释放资源
    • Lock是乐观的,基于假想没有冲突(CAS),如果获取资源失败,则重试获取,直至成功
  • 释放锁

    • Synchronized只有执行结束后才会释放锁,如果中间遇到某些原因阻塞(如:sleep),则其他线程也只能等待
    • Lock必须用try/catch方法修饰,并在finally区域内调用unlock方法释放锁,否则不会释放,造成死锁
  • 读写锁

    • Synchronized无法实现,读锁共享,写锁排他的类似功能,锁住后读写都没有区别,只能阻塞

    • Lock可以实现ReadLock和WriteLock

      • 读锁可以共享,但是读锁过程中,会阻塞写锁
      • 写锁期间,读写都会阻塞
  • 业务选型

    • 在资源竞争少的时候,Synchronized和Lock的性能相差不大
    • 但是在资源竞争大的时候,Lock会更好,因为Synchronized会浪费更多的资源在CPU频繁的切换上下文

总结

  • Lock锁是API层面的,Synchronized是CPU层面的
  • 相对来说,Lock锁更灵活;这是优点,同时也是缺点,需要程序员更加关注unLock的释放使用,避免死锁。
  • 尽管Synchronized比较重量级,但是JVM从JDK1.6开始也在不断地优化,支持锁升级,但是reentrantlock更强大,有tryLock不会傻傻的一直等,非常人性化,还能避免死锁。