在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; } // …… }