多线程安全问题案例1 单例注入的类中含非线程安全属性

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

 

 

你可能感兴趣的:(线程安全)