浅说 synchronized 和 ReentrantLock 的区别

synchronized 是 Java 内建的同步机制。它的作用简单来说就是当某个线程通过其获取到当前锁时,其他也想获取当前锁的线程,只能等待或者阻塞在那里。

其实上,在 Java 5 之前,synchronized 是 Java 程序实现同步的唯一方法。

再来说说 ReentrantLock, 也就是再入锁,它在 Java 5 中提供的锁实现,语义和 synchronized 基本相同。再入锁直接通过调用 lock() 方法获取,代码书写也更加面向对象,使用也更加灵活。另外,ReentrantLock 还提供了一些额外实用的特性,比如公平性,或者利用定义条件等。需要注意的是,我们需要显示的调用 unlock() 方法释放锁,不然会一直持有锁,这点需要注意。

关于 synchronizedReentrantLock 的性能,其实在早期的版本 synchronized 的确是个很重的操作(因为涉及到用户态切换到内核态),但是后续的 Java 版本中,Java 团队也是一直有持续的优化,包括底层实现方式的改变,引入偏斜锁,轻量级锁,重量级锁,锁的升降级等。

如此说来,其实在低竞争场景,性能表现可能还会优于 ReentrantLock 的。但是在高竞争条件下 ReentrantLock 的性能要大于 synchronized

总结

在实际的开发中,除非对性能有着极致的追求,否则我们不应该过分纠结于性能,还是要优先考虑代码书写结构的便利性和可维护性等