Java Regex Thread是安全的吗?

jmq*_*jmq 101 java regex multithreading

我有一个函数,它使用Pattern#compile和a Matcher来搜索模式的字符串列表.

此函数用于多个线程.每个线程都将传递给Pattern#compile创建线程时的唯一模式.线程和模式的数量是动态的,这意味着我可以Pattern在配置期间添加更多的s和线程.

synchronize如果使用正则表达式,我是否需要使用此功能?java线程中的正则表达式是否安全?

Vin*_*lds 128

是的,来自Pattern类的Java API文档

此(Pattern)类的实例是不可变的,并且可供多个并发线程使用.Matcher类的实例不适合此类使用.

如果您正在查看以性能为中心的代码,请尝试使用reset()方法重置Matcher实例,而不是创建新实例.这将重置Matcher实例的状态,使其可用于下一个正则表达式操作.实际上,在Matcher实例中维护的状态是导致它对并发访问不安全的原因.

  • 模式对象是线程安全的,但`compile()`方法可能不是.多年来,有两到三个错误导致多线程环境中的编译失败.我建议在同步块中进行编译. (16认同)
  • 是的,在Pattern类中引发了并发错误,并且您对同步访问的建议表示赞赏.但是,Pattern类的原始开发人员打算将Pattern类作为线程安全,这是任何Java程序员应该能够依赖的契约.坦率地说,我宁愿拥有线程局部变量并接受最小的性能损失,而不是依赖于合同的线程安全行为(除非我已经看过代码).正如他们所说的"线程很容易,正确的同步很难". (4认同)

ada*_*ost 11

Java中使用正则表达式的线程安全性

摘要:

Java正则表达式API旨在允许在多个匹配操作之间共享单个编译模式.

您可以安全地从不同的线程调用 相同模式的Pattern.matcher(),并安全地同时使用匹配器. Pattern.matcher()可以安全地构建匹配器而不需要同步.尽管该方法不是同步的,但是在Pattern类的内部,一个名为compiled的volatile变量总是在构造模式后设置,并在对matcher()的调用开始时读取. 这会强制引用Pattern的任何线程正确"看到"该对象的内容.

另一方面,您不应该在不同的线程之间共享匹配器.或者至少,如果你曾经这样做过,你应该使用显式同步.

  • @akf,顺便说一句,你应该注意到这是一个讨论网站(很像这个).我认为你发现的任何东西都没有比你在这里找到的信息更好或更差(也就是说,它不是詹姆斯戈斯林的真实话语). (2认同)