取自IBM developerWorks 文章:轻松使用线程: 减少争用。技术 3:锁崩溃另一种能提高性能的技术称为“锁崩溃”(请参阅清单 6)。回想一下, Vector 类的方法几乎都是同步的。假设您有一个 String 值的 Vector ,并想搜索最长的 String 。进一步假设您已经知道只会在末端添加元素,而且元素不会被删除,那么,像 getLongest() 方法所展示的那样访问数据是安全的(通常),该方法只是调用 elementAt() 来检索每个元素,简单地对 Vector 的元素作循环。 getLongest2() 方法非常相似,除了在开始循环之前获取 Vector 上的锁之外。这样做的结果是当 elementAt() 试图获取锁时,JVM 将注意到当前线程已经拥有锁,而且将不会参与争用。 getLongest2() 加大了同步块,这似乎违背了“放进去,取出来”的原则,但因为避免了很大量可能的同步,调度开销的时间损失也少了,速度仍然快得多。 在运行 Sun 1.3 JDK 的双处理器 Linux 系统上,拥有两个线程,仅仅循环调用 getLongest2() 的的测试程序比调用 getLongest() 的要快 10 倍以上。虽然两个程序的序列化程度相同,但前者调度开销的时间损失要少得多。这又是一个极端的示例,但它表明争用的调度开销并不是微不足道的。即使只运行一个线程,崩溃版的速度也要快约 30% :获取您已占用的锁比获取无人占用的锁要快得多。 
清单 6. 锁崩溃  Vector v;
  ...
 
 public String getLongest() {
    int maxLen = 0;
    String longest = null;    for (int i=0; i<v.size(); i++) {
      String s = (String) v.elementAt(i);
      if (s.length() > maxLen) {
        maxLen = s.length();
        longest = s;
      }
    }
    return longest;
  }  public String getLongest2() {
    int maxLen = 0;
    String longest = null;    synchronized (v) { 
      for (int i=0; i<v.size(); i++) {
        String s = (String) v.elementAt(i);
        if (s.length() > maxLen) {
          maxLen = s.length();
          longest = s;
        }  
      }  
      return longest;
    }
  }
 这是一种奇妙的方法,推翻了一般认为的无同步方法快于无争用的同步方法,这是为何?