Java结合Junit做并发测试用例。

1:上一篇博文,介绍了Synchronized 和 配合Spring @Transtaction使用。下面咱们做一个测试。

2:在做并发测试前,可以预先设计使用线程池的execute方法、还是submit,虽然submit方法最后还是调用了线程池的execute;但submit方法封装了一个返回Future的值。

3:测试代码

public class MultiThreadTestCase extends AbstractSpringContextTestSupport {

	@Autowired
	SynchronizedNoTransService synchronizedNoTransService;
	
	@Autowired
	SynchronizedService synchronizedService;
	
	@Test
	public void testUpdateBalance() throws Exception {
		int threadCount = 2;
		ExecutorService executorService = Executors.newFixedThreadPool(threadCount);
		
		List<Future<Integer>> futures = new ArrayList<Future<Integer>>();
		
		for (int x = 0; x < threadCount; x++) { 
			Callable<Integer> callable = new Callable<Integer>() {
				@Override
				public Integer call() throws Exception {
					synchronizedService.synMethodTwo();
					return 1;
				}
			};
			Future<Integer> submit = executorService.submit(callable);
			futures.add(submit);
		}

		List<Exception> exceptions = new ArrayList<Exception>();
		for (Future<Integer> future : futures) {
			try {
				future.get();
			} catch (Exception e) {
				exceptions.add(e);
				e.printStackTrace(System.err);
			}
		}
	}
	
}

SynchronizedService中synMethodTwo的方法,业务逻辑处理最后是更新账户信息;此时会出现并发可能。

(1)相同的数据并发更新。

         可以考虑同步方法设计。

(2)不同的数据并发更新

        

         不同数据并发更新账户信息,由于Spring data jpa 维护了version 版本的信息,在遍历线程池submit返回的Future,future.get()方法时,可以看到Console信息两个异常信息,StaleObjectStateException和ObjectOptimisticLockingFailureException异常信息。

        

         该问题的解决方法,可能要从业务设计上或者多任务并发编程上下点功夫,目前我还对这种高并发没有策略。

猜你喜欢

转载自nanjiwubing123.iteye.com/blog/2252899
今日推荐