/*  Taken from Paul Butcher: Seven Concurrency Models in Seven Weeks
 * Counting, chapter 1, location 373/7299
 * 
 * This is an example of bad code.  There is race condition (relative timing effect)
 * caused when calling the increment() method. This is because the increment()
 * method generates four lines of bytecode:
 *   getfield #2
 *   iconst_1
 *   iadd
 *   putfield #2
 * when t1 and t2 interleave those four lines of code, then one of them (t1 or t2)
 * will be storing an updated value of count that is computed on *old* data.
 * The four lines of bytecode need to be atomic -- i.e., not permitted interleaving.
 */

/* when you run this code, you will get a different answer every time */

public class Counting {
	
	public static void main (String[] args) throws InterruptedException {
		
		class Counter {
			private int count = 0;
			public void increment() { ++count; }
			public int getCount() { return count; }
			}
		
		final Counter counter = new Counter();
		
		class CountingThread extends Thread {
			public void run() {
				for (int x = 0; x < 10000; ++x)
					counter.increment();
			}
		}
		
		CountingThread t1 = new CountingThread();
		CountingThread t2 = new CountingThread();
		t1.start();  t2.start();
		t1.join();   t2.join();
		
		System.out.println(counter.getCount() );
	}
}
