The problem of one shared object reference between 100 threads.

来源:互联网 发布:怎么用软件开网店 编辑:程序博客网 时间:2024/05/19 03:44

These days I have stumbled one problem of one shared object reference between 100 threads. A RequestHanlder uses one method to fire 100 threads to fetch results from the DB, and another method to filter the result, then save the filtered results. The following codes are  to simulate this situation, there, a stack reference is shared in the Main Thread in the static, and it would be assigned new value in every thread, in other words, every thread would use a single stack to process the logic.

Apparently, there exists the problem of Synchronization, like the thirdlyTestError() in the below code.

Then the way to solve problem is to add the synchronized keyword to this method, like the firstlyTestSync() method in the below code, however, is this the best way to work out this problem?  then i change the share design of the stack, ask each thread to create its own stack, like the secondlyTestnewStack() method in the below code.

in order to compare the three methods,  the java.util.concurrent.CountDownLatch class is used to wait every 100 threads finish, then compute the costing interval time for the three cases including firsltyTestSync, secondlyTestNewStack, thirdlyTestError(). After the test, the thirdlyTestError behaved as expected that it was amiss evidently, besides, its performance was worst. Both secondlyTestNewStack and firsltyTestSync could work well without any defects, but the performance is hard to predict. Through the practical test, the result signified that the firstlyTestSync has better and more stable performance.

Results:

+++++++++++++firstlyTestSync The test cost time=187550ms+++++++++++++secondlyTestnewStack The test cost time=179780ms+++++++++++++firstlyTestSync The test cost time=181395ms+++++++++++++secondlyTestnewStack The test cost time=234837ms+++++++++++++firstlyTestSync The test cost time=181842ms+++++++++++++secondlyTestnewStack The test cost time=166697ms+++++++++++++firstlyTestSync The test cost time=181559ms+++++++++++++secondlyTestnewStack The test cost time=228198ms+++++++++++++firstlyTestSync The test cost time=178432ms+++++++++++++secondlyTestnewStack The test cost time=233138ms

Codes:

package stest;import java.util.Stack;import java.util.concurrent.CountDownLatch;public class TestStack implements Runnable{private static Stack<String> expressionStack = null;private static Stack<String> operanStack =null;private int runType=0;private CountDownLatch doneSignal;public static final int threadNum=100;public static final int testNum=5000000;public static void main(String[] args) {     expressionStack = new Stack<String>();   expressionStack.push("voiceMailIndex");   expressionStack.push("BJAA");   expressionStack.push("=");      firstlyTestSync();   secondlyTestnewStack();   thirdlyTestError();} public static void firstlyTestSync(){  CountDownLatch allDoneSignal=new CountDownLatch(threadNum);   long timeStart=System.currentTimeMillis();   Thread[] threads=new Thread[threadNum];   for(int i=0;i<threadNum;i++){   TestStack test = new TestStack();   test.runType=0;   test.doneSignal=allDoneSignal;   Thread testThread = new Thread(test);   testThread.start();   threads[i]=testThread;   }      try {allDoneSignal.await();} catch (InterruptedException e) {e.printStackTrace();}      long timeEnd=System.currentTimeMillis();      System.out.println("+++++++++++++firstlyTestSync The test cost time="+(timeEnd-timeStart)+"ms");   }  public static void secondlyTestnewStack(){   CountDownLatch allDoneSignal=new CountDownLatch(threadNum);   long timeStart=System.currentTimeMillis();   Thread[] threads=new Thread[threadNum];   for(int i=0;i<threadNum;i++){   TestStack test = new TestStack();   test.runType=1;   test.doneSignal=allDoneSignal;   Thread testThread = new Thread(test);   testThread.start();   threads[i]=testThread;   }try {allDoneSignal.await();} catch (InterruptedException e) {e.printStackTrace();}             long timeEnd=System.currentTimeMillis();     System.out.println("+++++++++++++secondlyTestnewStack The test cost time="+(timeEnd-timeStart)+"ms");   } public static void thirdlyTestError(){  CountDownLatch allDoneSignal=new CountDownLatch(threadNum);   long timeStart=System.currentTimeMillis();   Thread[] threads=new Thread[threadNum];   for(int i=0;i<threadNum;i++){   TestStack test = new TestStack();   test.runType=2;   test.doneSignal=allDoneSignal;   Thread testThread = new Thread(test);   testThread.start();   threads[i]=testThread;   }      try {allDoneSignal.await();} catch (InterruptedException e) {e.printStackTrace();}       long timeEnd=System.currentTimeMillis();    System.out.println("+++++++++++++thirdlyTestError The test cost time="+(timeEnd-timeStart)+"ms");   } @Overridepublic void run() {int j=0;for(int i=0;i<testNum;i++){ try{ switch(runType){ case 0:syncHandleRequest();break; case 1:newStackHandleRequest();break; case 2:errorHandleRequest();break; } }catch(Exception e){// e.printStackTrace(); j++; } } if(j!=0){System.out.println(runType+" ThreadId="+Thread.currentThread().getId()+" erros="+j+", total="+testNum+", success="+(testNum-j)); }else{System.out.println(runType+" ThreadId="+Thread.currentThread().getId()+" all success total="+testNum); } doneSignal.countDown();}   public static void newStackHandleRequest()throws Exception{   Stack<String> operanStack = new Stack<String>();   for (int i = 0; i < expressionStack.size(); i++) {  String temp = expressionStack.get(i);   operanStack.push(temp);  operanStack.push(null);}String elt="";for (int i = 0; i < 6; i++) {elt += operanStack.pop(); }if(!elt.equals("null=nullBJAAnullvoiceMailIndex")){    throw new Exception();}}    public static void errorHandleRequest()throws Exception{operanStack = new Stack<String>();for (int i = 0; i < expressionStack.size(); i++) {  String temp = expressionStack.get(i);   operanStack.push(temp);  operanStack.push(null);}String elt="";for (int i = 0; i < 6; i++) {elt += operanStack.pop(); }if(!elt.equals("null=nullBJAAnullvoiceMailIndex")){    throw new Exception();}}public synchronized static void syncHandleRequest()throws Exception{        operanStack = new Stack<String>();        for (int i = 0; i < expressionStack.size(); i++) {    String temp = expressionStack.get(i);     operanStack.push(temp);    operanStack.push(null);  }  String elt="";    for (int i = 0; i < 6; i++) {  elt += operanStack.pop();   }  if(!elt.equals("null=nullBJAAnullvoiceMailIndex")){      throw new Exception();  }}   private static void handleRequest(Stack<String> operanStack)throws Exception{for (int i = 0; i < expressionStack.size(); i++) {  String temp = expressionStack.get(i);   operanStack.push(temp);  operanStack.push(null);}String elt="";for (int i = 0; i < 6; i++) {elt += operanStack.pop(); }if(!elt.equals("null=nullBJAAnullvoiceMailIndex")){    throw new Exception();}}}





原创粉丝点击