import java.util.*;class Pair { // Not thread-safe
  private int x, y;
  public Pair(int x, int y) {
    this.x = x;
    this.y = y;
  }
  public Pair() { this(0, 0); }
  public int getX() { return x; }
  public int getY() { return y; }
  public void incrementX() { x++; }
  public void incrementY() { y++; }
  public String toString() {
    return "x: " + x + ", y: " + y;
  }
  public class PairValuesNotEqualException
  extends RuntimeException {
    public PairValuesNotEqualException() {
      super("Pair values not equal: " + Pair.this);
    }
  }
  // Arbitrary invariant -- both variables must be equal:
  public void checkState() {
    if(x != y)
      throw new PairValuesNotEqualException();
  }
}// Protect a Pair inside a thread-safe class:
abstract class PairManager {
  protected Pair p = new Pair();
  private List storage = new ArrayList();
  public synchronized Pair getPair() {
    // Make a copy to keep the original safe:
    return new Pair(p.getX(), p.getY());
  }
  protected void store() { storage.add(getPair()); }
  // A "template method":
  public abstract void doTask();
}// Synchronize the entire method:
class PairManager1 extends PairManager {
  public synchronized void doTask() {
    p.incrementX();
    p.incrementY();
    store();
  }
}// Use a critical section:
class PairManager2 extends PairManager {
  public void doTask() {
    synchronized(this) {
      p.incrementX();
      p.incrementY();
    }
    store();
  }
}class PairManipulator extends Thread {
  private PairManager pm;
  private int checkCounter = 0;
  private class PairChecker extends Thread {
    PairChecker() { start(); }
    public void run() {
      while(true) {
        checkCounter++;
        pm.getPair().checkState();
      }
    }
  }
  public PairManipulator(PairManager pm) {
    this.pm = pm;
    start();
    new PairChecker();
  }
  public void run() {
    while(true) {
      pm.doTask();
    }
  }
  public String toString() {
    return "Pair: " + pm.getPair() +
      " checkCounter = " + checkCounter;
  }
}public class CriticalSection {
  public static void main(String[] args) {
    // Test the two different approaches:
    final PairManipulator
      pm1 = new PairManipulator(new PairManager1()),
      pm2 = new PairManipulator(new PairManager2());
    new Timer(true).schedule(new TimerTask() {
      public void run() {
        System.out.println("pm1: " + pm1);
        System.out.println("pm2: " + pm2);
        System.exit(0);
      }
    }, 500); // run() after 500 milliseconds
  }
} ///:~我测试的输出结果是
pm1: Pair: x: 373845, y: 373845 checkCounter = 68832
pm2: Pair: x: 133935, y: 133935 checkCounter = 549925几个弱智问题
1.执行 start(); new PairChecker(); 后,doTask中对x,y的递增和PairChecker 线程中checkCounter的递增几乎同时开始的啊,两个线程优先级也一样,为啥最后checkCounter 比x和y少那么多???2.为什么pm2的x,y比pm1的x,y少, 而checkCounter 比Pm1的checkCounter 多很多呢?