Synchronized和Lock的用法和区别

1、Synchronized和Lock的用法和区别

1.synchronized是托管给JVM执行的,而Lock是Java写的控制锁的代码。 
2.synchronized原始采用的是CPU悲观锁机制,即线程获得的是独占锁。独占锁意味着其他线程只能依靠阻塞来等待线程释放锁。而在CPU转换线程阻塞时会引起线程上下文切换,当有很多线程竞争锁的时候,会引起CPU频繁的上下文切换导致效率很低。  
3.Lock用的是乐观锁方式。每次不加锁而是假设没有冲突而去完成某项操作,如果因为冲突失败就重试,直到成功为止。 
4.ReentrantLock必须在finally中释放锁,否则后果很严重,编码角度来说使用synchronized更加简单,不容易遗漏或者出错。 
5.ReentrantLock提供了可轮询的锁请求,他可以尝试的去取得锁,如果取得成功则继续处理,取得不成功,可以等下次运行的时候处理,所以不容易产生死锁,而synchronized则一旦进入锁请求要么成功,要么一直阻塞,所以更容易产生死锁。 
6.synchronized的话,锁的范围是整个方法或synchronized块部分;而Lock因为是方法调用,可以跨方法,灵活性更大。

2、Synchronized和Lock的用法和区别

synchronized 是Java的关键字,是Java的内置特性,在JVM层面实现了对临界资源的同步互斥访问,但 synchronized 粒度有些大,在处理实际问题时存在诸多局限性,比如响应中断等。Lock 提供了比 synchronized更广泛的锁操作,它能以更优雅的方式处理线程同步问题。    

在性能上来说,如果竞争资源不激烈,两者的性能是差不多的,而当竞争资源非常激烈时(即有大量线程同时竞争),此时Lock的性能要远远优于synchronized。所以说,在具体使用时要根据适当情况选择。

性能比较:

    在JDK1.5中,synchronized是性能低效的。因为这是一个重量级操作,它对性能最大的影响是阻塞的是实现,挂起线程和恢复线程的操作都需要转入内核态中完成,这些操作给系统的并发性带来了很大的压力。相比之下使用Java提供的Lock对象,性能更高一些。Brian Goetz对这两种锁在JDK1.5、单核处理器及双Xeon处理器环境下做了一组吞吐量对比的实验,发现多线程环境下,synchronized的吞吐量下降的非常严重,而ReentrankLock则能基本保持在同一个比较稳定的水平上。但与其说ReetrantLock性能好,倒不如说synchronized还有非常大的优化余地,于是到了JDK1.6,发生了变化,对synchronize加入了很多优化措施,有自适应自旋,锁消除,锁粗化,轻量级锁,偏向锁等等。导致在JDK1.6上synchronize的性能并不比Lock差。官方也表示,他们也更支持synchronize,在未来的版本中还有优化余地,所以还是提倡在synchronized能实现需求的情况下,优先考虑使用synchronized来进行同步。
当需要以下高级特性时,才应该使用Lock:可定时的、可轮询的与可中断的锁获取操作,公平队列,或者非块结构的锁。否则,请使用synchronized。
 

3、Synchronized和Lock的用法和区别

那么lock和synchronized的区别对比如下:
1)synchronized 在成功完成功能或者抛出异常时,虚拟机会自动释放线程占有的锁;而Lock对象在发生异常时,如果没有主动调用unLock()方法去释放锁,则锁对象会一直持有,因此使用Lock时需要在finally块中释放锁;
2)lock接口锁可以通过多种方法来尝试获取锁包括立即返回是否成功的tryLock(),以及一直尝试获取的lock()方法和尝试等待指定时间长度获取的方法,相对灵活了许多比synchronized;
3) 通过在读多,写少的高并发情况下,我们用ReentrantReadWriteLock分别获取读锁和写锁来提高系统的性能,因为读锁是共享锁,即可以同时有多个线程读取共享资源,而写锁则保证了对共享资源的修改只能是单线程的。
 

猜你喜欢

转载自blog.csdn.net/shipfei_csdn/article/details/81908834
今日推荐