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