WEB开发网
开发学院软件开发Java Java 理论与实践: 平衡测试,第 3 部分:用方面检... 阅读

Java 理论与实践: 平衡测试,第 3 部分:用方面检验设计约束

 2010-01-11 00:00:00 来源:WEB开发网   
核心提示: 要让清单 5 中的 DebuggingLock 版本有帮助,程序必须在测试时实际地发生死锁,Java 理论与实践: 平衡测试,第 3 部分:用方面检验设计约束(7),因为死锁通常依赖于计时和环境,所以清单 5 中的方法可能还不够,都可以在开发和测试中使用方面找出是否违犯了这些策略,不论是否在生产

要让清单 5 中的 DebuggingLock 版本有帮助,程序必须在测试时实际地发生死锁。因为死锁通常依赖于计时和环境,所以清单 5 中的方法可能还不够。清单 6 显示了另一个版本的 DebuggingLock,它不仅判断是否发生死锁,还会判断给定的一对锁是否由多个线程在不一致的顺序下得到。每次得到锁时,它都查看已经持有的锁的集合,对于每个锁,都记住在这个锁之前某个线程已经请求了这些锁。在试图获得锁之前,lock() 方法都查看已经持有的锁,如果在这个锁之后已经得到了其中一个锁,就抛出 AssertionError。这个实现的空间开销要比前一个版本大得多(因为需要跟踪在给定锁之前所有已经得到的锁),但是它能检测到更大泛围的 bug。它不会检测出所有可能的死锁 —— 只有由两个特定锁之间的不一致顺序造成的死锁,而这是最常见的情况。


清单 6. DebuggingLock 的替代版本,即使死锁没有后果,也能检查出不一致的锁定顺序
public class OrderHistoryLock extends ReentrantLock { 
  private static ThreadLocal<Set<OrderHistoryLock>> heldLocks = 
   new ThreadLocal<Set<OrderHistoryLock>>() { 
    public Set<OrderHistoryLock> initialValue() { 
      return new HashSet<OrderHistoryLock>(); 
    } 
  }; 
 
  private final Map<Lock, Boolean> predecessors 
    = new ConcurrentHashMap<Lock, Boolean>(); 
   
  public OrderHistoryLock() { super(); } 
   
  public OrderHistoryLock(boolean fair) { super(fair); } 
 
  public void lock() { 
    boolean alreadyHeld = isHeldByCurrentThread(); 
    for (OrderHistoryLock lock : heldLocks.get()) { 
      if (lock.predecessors.containsKey(this)) 
        throw new AssertionError("Possible deadlock between " 
         + this + " and " + lock); 
      else if (!alreadyHeld) 
        predecessors.put(lock, Boolean.TRUE); 
    } 
    super.lock(); 
    heldLocks.get().add(this); 
  } 
 
  public void unlock() { 
    super.unlock(); 
    if (!isHeldByCurrentThread()) 
      heldLocks.get().remove(this); 
  } 
} 

结束语

这里描述的方面属于策略实施方面。有些策略是应用程序设计的一部分,例如 “这些方法应当只从类 X 中调用” 或 “什么东西都不要使用 System.out 或 System.err”。其他策略是 API 的接口合约的一部分,例如 Swing 的单线程规则或 EJB 不应当创建线程或调用 AWT 之类的需求。在所有情况下,都可以在开发和测试中使用方面找出是否违犯了这些策略。不论是否在生产中使用方面,它都是测试工具包中的一个优秀工具。

上一页  2 3 4 5 6 7 

Tags:Java 理论 实践

编辑录入:爽爽 [复制链接] [打 印]
赞助商链接