本文共 874 字,大约阅读时间需要 2 分钟。
这个文章的起因和一个同事的激烈学术性讨论,快打起来那种。
我:ReentrantLock解决多路并发查询的数据合并方式更合适。
棒哥:用synchronized在资源竞争激烈的性能更好。 我:synchronized在资源竞争激烈的时候有极大的概率会进行锁升级,且锁的升级是不可逆的。 棒哥:ReentrantLock内部的乐观锁自旋比线程挂起更消耗cpu的资源。
存在即合理,我觉得单纯的认为某一种方式好或坏是一种片面的看法,这两种方式应该区分场景和并发量和处理时间来判定使用哪一种合适。特别是synchronized已经和我以前认知的不太一样了,JDK6后续的优化,让越来越多的开发者喜欢使用他。
JDK5中,synchronized是性能低效的,因为这是一个重量级操作,对性能的最大影响是阻塞的实现,挂起线程和恢复线程的操作,都需要转入内核态中完成,给并发带来了很大压力。
JDK6中synchronized加入了自适应自旋、锁消除、锁粗化、轻量级锁、偏向锁等一系列优化,官方也支持synchronized,提倡在synchronized能实现需求的前提下,优先考虑synchronized来进行同步。
ReentrantLock是标准的乐观锁的实现,内部while的循环,通过判断标识来判断锁是否被其他线程所持有,当其他线程所持有时,就会一直自旋判断锁是否被释放。 理解内部的原理之后,就很容易理解,如果资源竞争激烈,同时锁竞争激烈,使用乐观锁,就会很多线程中一直在循环等待,当线程数和执行时间到达一个临界值时,可能就会比线程挂起的效率更低,循环等待的开销就会大于线程挂起的开销。所以需要加锁的代码快执行时间普遍很长不建议使用ReentrantLock。 当资源竞争激烈,同时尝试获取锁的线程很多时,部分线程等待过久,如果这个时候使用synchronized,会导致锁慢慢膨胀,资源占有会越来越多。为了保证synchronized的性能,加锁的代码块需要保证,执行时间稳定,不会突然暴增。转载地址:http://zeugn.baihongyu.com/