在50个线程并发的情况下出现数组越界异常,经排查原因为某一个类为单例注入,但含有非线程安全属性。详细如下
1、异常现象:数据越界
- java.lang.ArrayIndexOutOfBoundsException: 1
- at org.apache.oro.text.regex.Perl5Matcher.__findFirst(Unknown Source)
- at org.apache.oro.text.regex.Perl5Matcher.__interpret(Unknown Source)
- at org.apache.oro.text.regex.Perl5Matcher.contains(Unknown Source)
- at *.*.*.at.AtHelper.doFilter(AtHelper.java:68)
- at *.*.*.at.AtHelper.render(AtHelper.java:121)
- at *.*.*.comment.service.CommentService.render(CommentService.java:301)
- at *.*.*.comment.service.CommentService.render(CommentService.java:290)
- at *.*.*.comment.service.CommentService.listByAppIdAppItemId(CommentService.java:325)
- at *.*.*.comment.CommentServiceTest$1.run(CommentServiceTest.java:42)
2、原因
*.*.*.at.AtHelper类为单例注入,
存在属性PatternMatcher matcher,初始化时赋值为matcher = new Perl5Matcher();
PatternMatcher为非线程安全,在多线程情况下导致内部数据越界
代码如下:
- public class AtHelper {
- // ……
- private PatternMatcher matcher = null;
- // ……
- public AtHelper() throws MalformedPatternException{
- // ……
- matcher = new Perl5Matcher();
- // ……
- }
- private List<String> doFilter(String content) {
- // ……
- while (matcher.contains(input, pattern) == true) {
- mResult = matcher.getMatch();
- String uid = StringUtil.substring(mResult.toString(), 1);
- uids.add(uid);
- }
- return uids;
- }
- // ……
- }
3、解决方法
去掉*.*.*.at.AtHelper类中属性PatternMatcher matcher
在需要的函数中定义变量PatternMatcher matcher = new Perl5Matcher();取代之
代码如下:
- public class AtHelper {
- // ……
- // ……
- public AtHelper() throws MalformedPatternException{
- // ……
- // ……
- }
- private List<String> doFilter(String content) {
- // ……
- PatternMatcher matcher = new Perl5Matcher();
- while (matcher.contains(input, pattern) == true) {
- mResult = matcher.getMatch();
- String uid = StringUtil.substring(mResult.toString(), 1);
- uids.add(uid);
- }
- return uids;
- }
- // ……
- }