昨天同事在写一个多线程代码的时候,出现了共享对象被修改的问题。
for(int i=1; i<=pageNo; i++){ searchDO.setPageSize(PER_PAGE); searchDO.setPageNo(i); Callable<List<String>> callable = new SearchThreadMethod("thread_"+i, searchDO); Future<List<String>> future = cuPool.submit(callable); if (future != null){ setAll.add(future); } }
可以看出红色代码部分,i被修改了;
想象一下,在一个多线程环境下,有两个线程持有了同一个的searchDO实例:
1,线程1调用setPageNo(),改变了pageNo这个字段
2,线程1中断
3,线程2调用setPageNo(),也改变了pageNo
4,线程1恢复,此时pageNo的值已经被线程2修改了
可想而知,结果并不是我们要的。
在我们常用的工具类中,比如DateFormat也不是线程安全的,所以在使用的时候需要特别注意。
解决线程安全问题的几种方法:
1,利用局部变量替代共享实例。
2,使用threadLocal
3,代码段同步,不过这个需要性能开销
4,使用第三方开发的线程安全的jar包
贴下今天看的两个帖子:
1,http://www.oschina.net/translate/dateformat-with-multiple-threads
2,http://www.infoq.com/cn/news/2012/06/ugly-code-12