java 如何线程安全的循环匹配正则表达式

码上中国博客 发布于 10/12 18:22
阅读 439
收藏 0

我目前的代码如下:

public static String getFirstPhoneNum(String phoneNumer) {
        List<String> regs = Lists.newArrayList("400\\d{7}(-\\d{4}|转\\d{4})?|400-\\d{3}-\\d{4}(-\\d{4}|转\\d{4})?\",\"1\\d{10}"
                , "1\\d{10}",
                "\\d{8}(-\\d{1,4}[^\\d]$)?|\\d{3}-?\\d{8}(-\\d{1,4}[^\\d]$)?|\\d{4}-?\\d{7,8}(-\\d{1,4}[^\\d]$)?|\\d{3,4}-?\\d{4}-?\\d{4}(-\\d{1,4}[^\\d]$)?");
        List<Integer> indexes = new ArrayList<>();
        for (String reg : regs) {
            boolean b = Pattern.matches(reg, phoneNumer);
            Pattern pattern = Pattern.compile(reg);
            Matcher matcher = pattern.matcher(phoneNumer);
            matcher.reset(phoneNumer); //TODO 是否会线程不安全
            Integer index = matcher.groupCount();
            if (matcher.find() && index > 0) {
                String phone = matcher.group(0);
                ......
            }
        }
        ......
        return "-";
    }

以上方法每个http请求会调用多次,发现在该方法调用量多的时候会造成线程不安全,看官方资料说Matcher线程不安全,请问我该如何写才能线程安全的完成上述循环匹配的业务。

加载中
1
ArchitectureMaster
ArchitectureMaster

 只需要在for循环里面使用synchronized把里面的代码断用排他锁给锁往,即标记为同步代码scope即可解决此问题。

for (String reg : regs) {
   synchronized(this){
    // 不安全方法代码块
 }
}

题主需要注意的是,如其它回答者说的那样,线程不安全是因为有公共的方法块或变量被多个线程同时访问到。很明显你这个static 方法是一个公共方法,也就是A线程和B线程可同时访问到这个static方法。而这时如果是实例对象则不存在安全问题,则你这个名为getFirstPhoneNum的方法如果被其它线程使用,只能以其它线程实例之后再使用的形式存在,而这样就不存在安全问题,每个线程使用这个方法会自动自己的实例方法。而你这个方法是static方法,在内存中只有一个,即被所有线程共享方法,这时A线程调用时,B线程也会调用,那这时就可能会出现错乱。举例:

matcher.reset(phoneNumer);/A线程调用到这一行重置了这个matcher表达式。

而后面的b线程如果调用的是Matcher matcher = pattern.matcher(phoneNumer);

你想想看这样b线程的结果会怎么样?就有可能匹配出来的结果不对,因为static方法中这个matcher对象只有一个,而多线程访问时并不是你的这个方法完了之后后面线程才能访问,而是同时,这样就会出错。所以一定要在for循环中将这个代码块给锁住,用this的意义在于只有当前线程的实例则能访问,其它线程虽然也有实例但不是this所以会在外面。保证了程序能被顺序调用。

题主这样设计的确有线程安全问题,问题非出在mather对象,而是你的static方法。

0
渐行0渐远
渐行0渐远

局部变量哪来的线程安全问题

0
s
shuaizai88

局部变量哪来的线程安全问题?求老大回答

0
爱De资格

局部变量当前线程独享

0
vvtf
vvtf

Pattern是线程安全的.

Matcher虽然不是, 但是你这里没有多线程问题.

0
山下农-山上仙
山下农-山上仙

你哪儿设计到线程不安全了,线程不安全是因为要操作共有变量导致的

你这连共有变量也没有

OSCHINA
登录后可查看更多优质内容
返回顶部
顶部