import java.util.Scanner; public class CountingThread implements Runnable{ //total for counting private long value; //how a thread identifies itself private int id; //declared as volatile --explain later private volatile boolean done; //public static long total = 0; public static Data shared = new Data(); public CountingThread(int id){ this.id = id; value = 0; done = false; } //run method gets called as a result of a call to //start public void run(){ while(!done){ value++; //total++; shared.addOne(); } System.out.printf("Thread %d has value %d\n", id, value); //once run is done, the thread ends } //request that is thread stop public void pleaseStop(){ done = true; } public long getValue(){ return value; } /** * @param args */ public static void main(String[] args) { CountingThread[] counters = new CountingThread[10]; for(int i = 0; i < counters.length; i++){ counters[i] = new CountingThread(i); //create a thread that runs the current counter Thread t = new Thread(counters[i]); //start the thread, which will cause run to be called. t.start(); } Scanner in = new Scanner(System.in); System.out.println("Type something to stop the threads: "); //wait for something to be typed in.next(); //ask each thread to stop for(CountingThread ct: counters){ ct.pleaseStop(); } //stall while the threads finish up System.out.println("Type somethihng to end: "); in.next(); long allValues = 0; for(CountingThread ct: counters){ allValues += ct.getValue(); } System.out.println("Sum of all values: " +allValues); System.out.println("Total: " + shared.getTotal()); } } class Data { private long total = 0; //only one thread can be executing a synchronized method at a time //a thread must get a lock (on this object) to run this method //it will unlock, when it is done public synchronized void addOne(){ total++; } public long getTotal(){ return total; } }