java - 多线程 Java 正则表达式

标签 java regex multithreading

我有一个生产者为 1、消费者为 M 的线程模式。制作者从光盘中读取原始文档并将其放入 LinkedBlockingQueue 中。然后每个消费者线程获取一个原始文档并使用类解析该文档

ParsedDoc article = parseDoc(rawDocument);

parseDoc 类是一组具有以下模式的大约 20 种方法:

public String clearContent(String document) {
  Pattern regex = Pattern.compile(pattern);
  Matcher matcher = regex.matcher(document);
  matcher.find();
  ....
}

public String removeHTML(String document) {
  Pattern regex = Pattern.compile(pattern);
  Matcher matcher = regex.matcher(document);
  matcher.replaceAll("");
  ....
}

我面临的问题是代码在我的本地(2 核)机器上运行得相当快。但是当我在 8 核机器上运行相同的代码时,消费者性能下降到几乎停顿。我试图优化 jvm 选项但无济于事。删除正则表达式处理步骤可在 8 核上实现预期的 x4 性能提升。所以问题是正则表达式。我意识到 Pattern 是线程安全的,匹配器可能需要重置()。但问题是如何重新设计正则表达式库(在 parseDoc 类中),以便它在 M 个消费者之间是线程安全的。

任何帮助将不胜感激

谢谢

最佳答案

编译正则表达式很慢。对于给定的模式,您应该只执行一次。除非示例中显示的 pattern 变量在每次调用时确实不同,否则 Pattern 实例可能是 static 类成员。 Pattern 对于多个线程并发使用来说是明确安全的。 (所有可修改的状态都由 Matcher 持有。)

由于 Matcher 被限制在单个线程的堆栈中,因此您无需担心任何线程问题。不要尝试重用 Matcher。可以做到,但如果与正则表达式编译相比,回收它们可以节省很多时间,我会感到惊讶。

关于java - 多线程 Java 正则表达式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9756453/

相关文章:

java - 如何在 Google Cloud Compute Engine 中部署 Spring Boot 应用程序?

java - Spring Boot 尝试解析不在我的 xml 中的 bean

java - 将 Map<String, List<Integer>> 转换为 Map<String, int[]>

regex - 从电子邮件地址中提取域名的一行代码

PHP 正则表达式 [只接受选定的字符]

c# - 如何在azure辅助角色中同时启动处理任务

java - 将生成的流保存到 ArrayList 中

regex - 使用正则表达式进行 ipv6 验证

C# 线程问题和最佳实践

java - 内核oops中的Java PID可以属于一个线程吗?