////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // author: qingzhe huang // email: qingz_hu@cse.concordia.ca // date: oct. 1, 2006 // purpose: This little example tries to show you how context switch may corrupt your data when your // program is not properly synchronized with global data access // 1. since java 1.2.1 doesn't have class CyclicBarrier, I have to make it myself to barrier all // threads at beginning so that roughly all threads start running at same time. // 2. I create two group of equal number threads. One group try to increase the global variable "myPrice" // The other group try to decrease it. Since their number are equal, the balance should remain unchanged if // everything goes well. // 3. In order to make context switch happen in java 1.2.1, you must have a "sleep" or "yield" in function // "incPrice" and/or "decPrice". In java 1.4 or up, even you don't have this deliberate "waiting", your // balance still is not unchanged which means data corrupted because the threading-mode is "preemptive". // 4. In java 1.2.1, you can play with the "sleep" in "incPrice" or "decPrice" by setting up different time to // sleep, say 0 or 200 etc. and observe what is the result. Do they have patterns? Or remain fixed with one // setting? Or you are in the mood for adventure, try random number with Rand.nextInt(100); Or modify the // "MaxThreadNumber" to see what may change or not? //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// import java.util.*; public class MyExample { public static final int MaxThreadNumber=30; ////////////////////////////////////// //here we declare two equal number of array of threads and initialize them public static IncThread[] incThreadArray=new IncThread[MaxThreadNumber]; public static DecThread[] decThreadArray=new DecThread[MaxThreadNumber]; ////////////////////////////////// //a small skill to stop all created threads run one by one is to use //a barrier to "stop them until all threads are ready //as java 1.2 doesn't have this "CyclicBarrier class, I have to make it myself //////////////////////////////////////////////// public static int threadCounter=0; public static Random rand=new Random(); //here it is the one we are watching... public static int myPrice; public static void main(String args[]) { try { myPrice=5000; System.out.println("before thread testing starts, let's see the balance of myPrice: "+myPrice); System.out.println("Since we are using equal number of threads to run increasing and decreasing, if"); System.out.println(" our system is properly synchronized, after testing the balance should remain unchanged."); //////////////////////////////////// //since we have a "barrier" setup, the threads won't start until all are ready for (int i=0; i If you comment out this statement, the thread will run through in java 1.2.1 //---> then nothing seems happened and you won't be able to observe the different //---> balance problem due to context switch Thread.sleep(rand.nextInt(500)); } catch(Exception er) { System.out.println(er); } myPrice=temp; } public void run() { try { threadCounter++; while (threadCounter If you comment out this statement, the thread will run through in java 1.2.1 //---> then nothing seems happened and you won't be able to observe the different //---> balance problem due to context switch Thread.sleep(rand.nextInt(500)); } catch(Exception er) { System.out.println(er); } myPrice=temp; } public void run() { try { threadCounter++; while (threadCounter