import java.awt.Container; import java.awt.Dimension; import java.awt.FlowLayout; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import javax.swing.JButton; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JPanel; /** * An example to demonstrate race conditions. One thread deposits $1000 in $10 increments while * a second thread withdraws $1000 in $10 increments. In the end, the balance should be the same * as at the beginning - $1000. With race conditions, the ending result can be different. */ public class BankDemo implements AccountListener { // The label where the balance is displayed. private JLabel balanceLabel; private Account account; public BankDemo() { JFrame frame = new JFrame(); Container contentPane = frame.getContentPane(); contentPane.setLayout (new FlowLayout()); JPanel counter1Panel = new JPanel(); balanceLabel = new JLabel(""); balanceLabel.setMinimumSize(new Dimension(50, 15)); counter1Panel.add(balanceLabel); JButton runButton = new JButton("Run again"); runButton.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent arg0) { init(); } }); counter1Panel.add(runButton); contentPane.add(counter1Panel); frame.setSize(200, 200); frame.setVisible(true); init(); } /** * */ private void init() { account = new Account(); account.addListener(this); // Create first thread Withdrawer r = new Withdrawer(account); final Thread t = new Thread(r); // Create second thread Depositer r2 = new Depositer(account); final Thread t2 = new Thread(r2); t.start(); t2.start(); } public void balanceChanged(int newBalance) { System.out.println(newBalance); balanceLabel.setText("" + newBalance); } /** * @param args */ public static void main(String[] args) { BankDemo bank = new BankDemo(); } }