Eu tenho uma função que usa Pattern#compile
e Matcher
para pesquisar uma lista de strings para um padrão.
Esta função é usada em vários threads. Cada thread terá um padrão exclusivo passado para o Pattern#compile
quando o thread for criado. O número de threads e padrões são dinâmicos, o que significa que posso adicionar mais se Pattern
threads durante a configuração.
Preciso colocar um synchronize
nesta função se ela usa regex? O regex no thread de java é seguro?
fonte
compile()
método pode não ser. Houve dois ou três bugs ao longo dos anos que fizeram com que a compilação falhasse em ambientes multithread. Eu recomendaria fazer a compilação em um bloco sincronizado.Thread-safety com expressões regulares em Java
fonte
Embora você precise lembrar que a segurança do thread também deve levar em conta o código ao redor, você parece estar com sorte. O fato de que Matchers são criados usando o método de fábrica de matcher do Pattern e não possuem construtores públicos é um sinal positivo. Da mesma forma, você usa o método estático de compilação para criar o padrão abrangente .
Então, em resumo, se você fizer algo como o exemplo:
você deve estar indo muito bem.
Siga o exemplo de código para maior clareza: observe que este exemplo implica fortemente que o Matcher assim criado é thread-local com o Padrão e o teste. Ou seja, você não deve expor o Matcher assim criado a quaisquer outros threads.
Francamente, esse é o risco de qualquer questão de thread-safety. A realidade é que qualquer código pode se tornar inseguro para thread se você tentar o suficiente. Felizmente, existem livros maravilhosos que nos ensinam uma série de maneiras de arruinar nosso código. Se ficarmos longe desses erros, reduziremos muito nossa própria probabilidade de problemas de encadeamento.
fonte
Uma rápida olhada no código de
Matcher.java
mostra um monte de variáveis de membro, incluindo o texto que está sendo correspondido, matrizes para grupos, alguns índices para manter a localização e algunsboolean
s para outro estado. Tudo isso aponta para um statefulMatcher
que não se comportaria bem se acessado por váriosThreads
. O mesmo acontece com o JavaDoc :Isso só é um problema se, como @Bob Cross aponta, você se esforça para permitir o uso de seus programas
Matcher
separadosThread
. Se você precisar fazer isso e achar que a sincronização será um problema para o seu código, uma opção que você tem é usar umThreadLocal
objeto de armazenamento para manter umMatcher
por thread de trabalho.fonte
Para resumir, você pode reutilizar (manter em variáveis estáticas) o (s) padrão (ões) compilado (s) e dizer a eles para fornecerem novos Matchers quando necessário para validar aqueles pattens regex contra alguma string
consulte http://zoomicon.wordpress.com/2012/06/01/validating-e-mails-using-regular-expressions-in-java/ (próximo ao final) sobre o padrão RegEx usado acima para validar e-mails ( caso não se enquadre nas necessidades de validação de e-mail conforme postado aqui)
fonte
static {}
? Você pode embutir essa inicialização de variável e fazer oPattern
final
também.private static final Pattern emailPattern = Pattern.compile(EMAIL_PATTERN);
é melhor.