原则上,我们在编写同步块的时候,同步块的范围应当尽量小——只在共享数据的实际作用域中才进行同步,这样是为了使得需要同步的操作数量尽可能小,如果存在锁竞争,那等待锁的线程也能尽快的拿到锁。
大部分情况下,这种原则是正确的,但是如果一系列的连续操作都需要对同一个对象进行加锁和解锁,甚至加锁操作时出现在循环体中,那即使没有线程竞争,频繁地进行互斥同步操作也会导致不需要的性能损耗。
public String cancatString(String s1, String s2, String s3){
StringBuffer sb = new StringBuffer();
sb.append(s1);
sb.append(s2);
sb.append(s3);
return sb.toString();
}
上面代码中,连续的append方法就属于这种情况。这时虚拟机就会把锁同步的范围扩展(粗化)到整个操作序列的外部,即第一个append()操作之前直至最后一个append()操作之后,这样只需要加锁一次就可以了。
网友评论