У меня есть функция, которая использует Pattern#compile
и Matcher
для поиска шаблона в списке строк.
Эта функция используется в нескольких потоках. Каждый поток будет иметь уникальный шаблон, передаваемый в Pattern#compile
при создании потока. Количество потоков и шаблонов является динамическим, что означает, что я могу добавить больше Pattern
потоков и потоков во время настройки.
Нужно ли использовать synchronize
эту функцию, если она использует регулярное выражение? Является ли регулярное выражение в потоке Java безопасным?
compile()
метод может быть нет. За прошедшие годы было обнаружено две или три ошибки, которые приводили к сбою компиляции в многопоточных средах. Я бы рекомендовал делать компиляцию в синхронизированном блоке.Поточная безопасность с регулярными выражениями в Java
источник
Хотя вам нужно помнить, что безопасность потоков также должна учитывать окружающий код, вам, похоже, повезло. Тот факт, что сопоставители создаются с использованием метода фабрики сопоставлений Pattern и не имеют общедоступных конструкторов, является положительным знаком. Точно так же вы используете статический метод compile для создания охватывающего Pattern .
Короче говоря, если вы сделаете что-то вроде примера:
у тебя все должно быть хорошо.
Продолжение примера кода для ясности: обратите внимание, что этот пример строго подразумевает, что созданный таким образом Matcher является локальным для потока с шаблоном и тестом. То есть вы не должны открывать созданный таким образом Matcher для каких-либо других потоков.
Честно говоря, это риск возникновения вопросов о безопасности потоков. Реальность такова, что любой код можно сделать небезопасным для потоков, если вы достаточно постараетесь. К счастью, есть замечательные книги, которые учат нас множеству способов испортить наш код. Если мы избегаем этих ошибок, мы значительно уменьшаем нашу собственную вероятность возникновения проблем с потоками.
источник
Беглый взгляд на код
Matcher.java
показывает набор переменных-членов, включая сопоставляемый текст, массивы для групп, несколько индексов для сохранения местоположения и несколькоboolean
s для другого состояния. Все это указывает на состояниеMatcher
, которое не будет вести себя должным образом, если к нему будут обращаться несколькоThreads
. Так же как и JavaDoc :Это проблема только в том случае, если, как указывает @Bob Cross, вы изо всех сил разрешаете использовать свой
Matcher
в отдельныхThread
s. Если вам нужно это сделать и вы думаете, что синхронизация будет проблемой для вашего кода, у вас есть вариант - использоватьThreadLocal
объект хранилища для поддержкиMatcher
каждого рабочего потока.источник
Подводя итог, вы можете повторно использовать (сохранять в статических переменных) скомпилированные шаблоны и сказать им, чтобы они предоставили вам новые сопоставители, когда это необходимо, для проверки этих шаблонов регулярных выражений на некоторой строке
см. http://zoomicon.wordpress.com/2012/06/01/validating-e-mails-using-regular-expressions-in-java/ (ближе к концу) относительно шаблона RegEx, использованного выше для проверки электронной почты ( в случае, если он не подходит для проверки электронной почты, как это размещено здесь)
источник
static {}
? Вы можете встроить инициализацию этой переменной, а также сделатьPattern
final
.private static final Pattern emailPattern = Pattern.compile(EMAIL_PATTERN);
лучше.