The problem of one shared object reference between 100 threads.

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");
		   
	}
	 
	@Override
	public 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();
		}
	}
}





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值