Hacker News new | ask | show | jobs
by gbacon 2879 days ago
At the bottom of JavaUnitTestChallengeSolved[0], William Underwood posted the test below and claims that it always catches the `notify()` problem. He did not mention using TLA+.

    public static void testConcurrency() throws InterruptedException {
      final int[] threadsFinished = new int[]{0};
      final BoundedBuffer buffer = new BoundedBuffer();

      Thread thread1 = new Thread() {
        public void run() {
          synchronized (buffer) {
            synchronized (this) {
              this.notifyAll();
            }
            try {
              buffer.wait();
            } catch (InterruptedException e) {}
            threadsFinished[0]++;
          }
        }
      };
      Thread thread2 = new Thread() {
        public void run() {
          synchronized (buffer) {
            synchronized (this) {
              this.notifyAll();
            }
            try {
              buffer.wait();
            } catch (InterruptedException e) {}
            threadsFinished[0]++;
          }
        }
      };

      synchronized (thread1) {
        thread1.start();
        thread1.wait();
      }
      synchronized (thread2) {
        thread2.start();
        thread2.wait();
      }
      synchronized (buffer) {
        buffer.put("");
        thread1.join(1000);
        thread2.join(1000);
      }
      assertEquals("Not all test threads were awoken!", 2, threadsFinished[0]);
    }
[0]: http://wiki.c2.com/?JavaUnitTestChallengeSolved
1 comments

That's just testing that all of the test threads are awake after they run once. It only does one buffer operation (the `put` in `synchronized buffer`), and we trivially know it's "broken" if there are only puts and no gets. It's also using two threads for a buffer length of 4. This isn't actually surfacing the bug, just something that looks somewhat like the bug if you already know what the bug is.