1:import javax.swing.*;
   2:import java.awt.*;
   3:import java.awt.event.*;
   4:
   5:/**
   6: * A simple program to demonstrate data races
   7: *  
   8: * Author: John C. Linford (jlinford@vt.edu)
   9: * Date: 25 August 2005
  10: * License: Public Domain
  11: */
  12:public class DataRaceApplet extends JApplet {
  13:
  14:    private int[] shared = new int[1];
  15:    private Thread t1, t2;
  16:    
  17:    private JTextArea outputArea = new JTextArea();
  18:    private JScrollPane outputScroller = new JScrollPane(outputArea);
  19:    private JButton runBtn = new JButton("Race!");
  20:    
  21:    
  22:    public DataRaceApplet() {
  23:        setLayout(new BorderLayout());
  24:        this.add(runBtn, BorderLayout.SOUTH);
  25:        this.add(outputScroller, BorderLayout.CENTER);
  26:        
  27:        runBtn.addActionListener(new ActionListener() {
  28:            public void actionPerformed(ActionEvent evt) {
  29:                race();
  30:            }
  31:        });
  32:    }
  33:    
  34:    
  35:    private void race() {
  36:        
  37:        outputArea.setText("");
  38:        
  39:        // Create a first thread to increment shared
  40:        t1 = new Thread() {
  41:            public void run() {
  42:                int copy = 0; // Stores a copy of shared to detect races
  43:
  44:                while(t1 != null) {
  45:                    // Make a copy of shared in a safe way
  46:                    synchronized(shared) {
  47:                        copy = shared[0];
  48:                    }
  49:
  50:                    // Increment shared unsafely (possible race)
  51:                    shared[0] = shared[0] + 1;
  52:
  53:                    // Check for a race condition in a safe way
  54:                    synchronized(shared) {
  55:                        outputArea.append("[t1] -- Shared: " + shared[0] + ".\n");
  56:                        if(shared[0] - 1 != copy) {
  57:                            outputArea.append("[t1] -- Data Race!  Had " + shared[0] + " when I expected " + (copy + 1) + ".\n");
  58:                            t1 = t2 = null;
  59:                        }
  60:                    }
  61:                }
  62:            }
  63:        };
  64:        
  65:        // Create a second thread to increment shared
  66:        t2 = new Thread() {
  67:            public void run() {
  68:                int copy = 0; // Stores a copy of shared to detect races
  69:
  70:                while(t2 != null) {
  71:                    // Make a copy of shared in a safe way
  72:                    synchronized(shared) {
  73:                        copy = shared[0];
  74:                    }
  75:
  76:                    // Increment shared unsafely (possible race)
  77:                    shared[0] = shared[0] + 1;
  78:
  79:                    // Check for a race condition in a safe way
  80:                    synchronized(shared) {
  81:                        outputArea.append("[t2] -- Shared: " + shared[0] + ".\n");
  82:                        if(shared[0] - 1 != copy) {
  83:                            outputArea.append("[t2] -- Data Race!  Had " + shared[0] + " when I expected " + (copy + 1) + ".\n");
  84:                            t1 = t2 = null;
  85:                        }
  86:                    }
  87:                }
  88:            }
  89:        };
  90:        
  91:        t1.start();
  92:        t2.start();
  93:    }
  94:}