synchronized 与 lock 区别

我们需要先从线程来讲起,相关基本概念这里就不做过多的阐述,都太基本了,有需要可以参考:synchronized 相关概念。这里先从线程状态聊起

1、线程状态

 

 线程共有 5 种状态:

  1. 新建状态:新建线程对象,并没有调用start()方法之前
  2. 就绪状态:调用start()方法之后线程就进入就绪状态,但是并不是说只要调用start()方法线程就马上变为当前线程,在变为当前线程之前都是为就绪状态。值得一提的是,线程在睡眠和挂起中恢复的时候也会进入就绪状态哦。
  3. 运行状态:线程被设置为当前线程,开始执行run()方法。就是线程进入运行状态
  4. 阻塞状态:线程被暂停,比如说调用sleep()方法后线程就进入阻塞状态
  5. 死亡状态:线程执行结束

2、锁类型

  1、可重入锁:包含 synchronized 和 ReentrantLock,即在执行对象中所有同步方法不用再次获得锁。

  2、可中断锁:Lock 为可中断锁,而 synchronized 并不是。即在等待获取锁的过程中是可以被中断的。

  3、公平锁:ReentrantLock 和 ReentrantReadWriteLock 是公平锁,即按等待获取锁的线程等待时间进行获取,等待时间长的具有优先获取锁的权利

  4、读写锁:ReadWriteLock 和 ReentrantReadWriteLock,对资源读取和写入的时候拆分成 2 部分处理,读的时候可以多线程一起读,写的时候必须同步地写。

具体区别为:

 类别  synchronized  Lock
 存在层次  Java的关键字,在jvm层面上  是一个接口
 锁的释放

1、以获取锁的线程执行完同步代码,释放锁 

2、线程执行发生异常,jvm会让线程释放锁

 在finally中必须释放锁,不然容易造成线程死锁
 锁的获取

 假设A线程获得锁,B线程等待。

 如果A线程阻塞,B线程会一直等待

分情况而定,Lock有多个锁获取的方式,大致就是可以尝试获得锁,线程可以不用一直等待(可以通过tryLock判断有没有锁)
 锁状态  无法判断  可以判断
 锁类型  可重入 不可中断 非公平  可重入 可判断 可公平(两者皆可)
 性能  少量同步 大量同步
  1、Lock可以提高多个线程进行读操作的效率。(可以通过readwritelock实现读写分离)
  2、在资源竞争不是很激烈的情况下,Synchronized的性能要优于ReetrantLock,但是在资源竞争很激烈的情况下,Synchronized的性能会下降几十倍,但是ReetrantLock的性能能维持常态;
  3、ReentrantLock提供了多样化的同步,比如有时间限制的同步,可以被Interrupt的同步(synchronized的同步是不能Interrupt的)等。在资源竞争不激烈的情形下,性能稍微比synchronized差点点。但是当同步非常激烈的时候,synchronized的性能一下子能下降好几十倍。而ReentrantLock确还能维持常态。

 

 

 

 

 

 

 

 

 

 

 

 

如果想要了解 Lock 相关内容,请查看 Lock 详解

posted @ 2020-04-26 11:28  星火燎原智勇  阅读(353)  评论(0编辑  收藏  举报