Race Conditions

1. CounterApplet.java: (Download Source)

import java.applet.Applet;
import java.awt.*;

public class BuggyCounterApplet extends Applet
                                implements Runnable{
  private static int totalNum = 0;
  private int loopLimit = 5;

  public void start() {
    Thread t;
    for(int i=0; i<3; i++) {
      t = new Thread(this);
      t.start();
    }
  }

  private void pause(double seconds) {
    try { Thread.sleep(Math.round(1000.0*seconds)); }
    catch(InterruptedException ie) {}
  }
  
  public void run() {
    int currentNum = totalNum;
    System.out.println("Setting currentNum to "
                       + currentNum);
    totalNum = totalNum + 1;
    for(int i=0; i<loopLimit; i++) {
      System.out.println("Counter "
                         + currentNum + ": " + i);
      pause(Math.random());
    }
  }
}

     Demo (Turn on Java Console for demo output).

2. Usual Output

Setting currentNum to 0
Counter 0: 0
Setting currentNum to 1
Counter 1: 0
Setting currentNum to 2
Counter 2: 0
Counter 2: 1
Counter 1: 1
Counter 0: 1
Counter 2: 2
Counter 0: 2
Counter 1: 2
Counter 1: 3
Counter 0: 3
Counter 2: 3
Counter 1: 4
Counter 2: 4
Counter 0: 4

3. Occasional Output

Setting currentNum to 0
Counter 0: 0
Setting currentNum to 1
Setting currentNum to 1
Counter 0: 1
Counter 1: 0
Counter 1: 0
Counter 0: 2
Counter 0: 3
Counter 1: 1
Counter 0: 4
Counter 1: 1
Counter 1: 2
Counter 1: 3
Counter 1: 2
Counter 1: 3
Counter 1: 4
Counter 1: 4

4. Solution(?) -- Do things in a single step

public void run() {
  int currentNum = totalNum++;
  System.out.println("Setting currentNum to "
                     + currentNum);
  for(int i=0; i<loopLimit; i++) {
    System.out.println("Counter "
                       + currentNum + ": " + i);
    pause(Math.random());
  }
}

© 1996-99 Marty Hall, 1999 Lawrence M. Brown