3.锁粗化
锁粗化是指,将多个连续的加锁、解锁操作连接在一起,扩展成一个范围更大的锁。
我只听说锁“细化”可以提高程序的执行效率,也就是将锁的范围尽可能缩小,这样在锁竞争时,等待获取锁的线程才能更早的获取锁,从而提高程序的运行效率,但锁粗化是如何提高性能的呢?
没错,锁细化的观点在大多数情况下都是成立了,但是一系列连续加锁和解锁的操作,也会导致不必要的性能开销,从而影响程序的执行效率,比如这段代码:
public String method() { StringBuilder sb = new StringBuilder(); for (int i = 0; i < 10; i++) { // 伪代码:加锁操作 sb.append("i:" + i); // 伪代码:解锁操作 } return sb.toString(); }
这里我们不考虑编译器优化的情况,如果在 for 循环中定义锁,那么锁的范围很小,但每次 for 循环都需要进行加锁和释放锁的操作,性能是很低的;但如果我们直接在 for 循环的外层加一把锁,那么对于同一个对象操作这段代码的性能就会提高很多,如下伪代码所示:
public String method() { StringBuilder sb = new StringBuilder(); // 伪代码:加锁操作 for (int i = 0; i < 10; i++) { sb.append("i:" + i); } // 伪代码:解锁操作 return sb.toString(); }
锁粗化的作用:如果检测到同一个对象执行了连续的加锁和解锁的操作,则会将这一系列操作合并成一个更大的锁,从而提升程序的执行效率。