多线程 - synchronized 和 ReentrantLock的区别

标签: java基础 多线程

  synchronizedReentrantLock都是多线程中的上锁操作,目的是使程序互斥执行,从而保证对资源的访问是线程安全的。


1. 使用方法

  synchronized是一个关键字,可以修饰方法、语句块。但ReentrantLock是一个类,使用时必须在用户类中组合实现这个类,并调用lock(),unlock()等方法来控制。


2. 锁定机制

  ReentrantLock 拥有锁投票定时锁等候中断锁等候等机制。

例如:线程A和B都要获取对象Obj的锁定,假设A获取了对象Obj锁,B将等待A释放对Obj的锁定。

  使用synchronized,如果A不释放,B将无限阻塞直到A释放锁;
  使用ReentrantLock,如果A不释放,可以使B在等待了足够长的时间以后,中断等待,而干别的事情。


3. 锁定释放

  synchronized是在JVM层面上实现的,不但可以通过一些监控工具监控synchronized的锁定,而且在代码执行时出现异常,JVM会自动释放锁定;但是ReentrantLock则不行,它是通过代码实现锁定的,要保证锁一定会被释放,就必须将unLock()放到finally{}中。


4. 性能对比

  synchronized编译器会优化,可读性好,资源宽松时性能也不错,但缺点资源竞争激励时性能太差,能下降几十倍。ReetrantLock类性能稳定,控制灵活,但复杂性也相应提高,一般优化时才会用到。


5. 附: ReentrantLock四种锁定方法

  a) lock() : 如果获取了锁,立即返回,如果别的线程正持有锁,当前线程则一直处于休眠状态,直到获取锁(与synchronized等价);

  b) tryLock() : 如果获取了锁,立即返回true,如果别的线程正持有锁,立即返回false。利用这一特性,可以终止等待先干别的

  c) tryLock(long timeout,TimeUnit unit) : 如果获取了锁,立即返回true,如果别的线程正持有锁,会等待参数给定的时间,在等待的过程中,如果获取了锁,就返回true,如果等待超时,返回false;

  d) lockInterruptibly() : 如果获取了锁,立即返回,如果没有获取锁定,当前线程处于休眠状态,直到获得锁,或者当前线程被别的线程中断

posted @ 2017-03-23 11:51  斑鱼  阅读(146)  评论(0编辑  收藏  举报