Es Java Regex Thread Safe?
multithreading (5)
Para resumir, puede reutilizar (mantener variables estáticas) los patrones compilados y decirles que le den Matchers nuevos cuando sea necesario para validar esos patrones de expresiones regexáneas contra alguna cadena.
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* Validation helpers
*/
public final class Validators {
private static final String EMAIL_PATTERN = "^[_A-Za-z0-9-]+(//.[_A-Za-z0-9-]+)*@[A-Za-z0-9-]+(//.[A-Za-z0-9-]+)*(//.[A-Za-z]{2,})$";
private static Pattern email_pattern;
static {
email_pattern = Pattern.compile(EMAIL_PATTERN);
}
/**
* Check if e-mail is valid
*/
public static boolean isValidEmail(String email) {
Matcher matcher = email_pattern.matcher(email);
return matcher.matches();
}
}
ver http://zoomicon.wordpress.com/2012/06/01/validating-e-mails-using-regular-expressions-in-java/ (cerca del final) con respecto al patrón RegEx utilizado anteriormente para validar los correos electrónicos ( en caso de que no se ajuste a las necesidades de validación de correo electrónico tal como se publica aquí)
Tengo una función que usa la Pattern#compile
y un Matcher
para buscar una lista de cadenas para un patrón.
Esta función se usa en múltiples hilos. Cada hilo tendrá un patrón único que se pasará a la Pattern#compile
cuando se cree el hilo. La cantidad de hilos y patrones son dinámicos, lo que significa que puedo agregar más Pattern
e hilos durante la configuración.
¿Debo synchronize
esta función si usa expresiones regulares? ¿Es segura la expresión regular en el hilo de Java?
Si bien debes recordar que la seguridad del hilo también debe tener en cuenta el código que lo rodea, parece que estás de suerte. El hecho de que Matchers se haya creado utilizando el método de fábrica de matcher de Pattern y carezca de constructores públicos es una señal positiva. Del mismo modo, utiliza el método estático de compile para crear el Pattern abarcador.
Entonces, en resumen, si haces algo como el ejemplo:
Pattern p = Pattern.compile("a*b");
Matcher m = p.matcher("aaaaab");
boolean b = m.matches();
deberías estar haciendo bastante bien.
Seguimiento del ejemplo del código para mayor claridad: tenga en cuenta que este ejemplo implica fuertemente que el Matcher así creado es thread-local con el Patrón y la prueba. Es decir, no debe exponer el Matcher así creado a ningún otro hilo.
Francamente, ese es el riesgo de cualquier pregunta sobre seguridad de hilos. La realidad es que cualquier código puede hacerse inseguro si se esfuerza lo suficiente. Afortunadamente, hay books wonderful que nos enseñan un montón de maneras en que podemos arruinar nuestro código. Si nos mantenemos alejados de esos errores, reducimos en gran medida nuestra propia probabilidad de problemas.
Una mirada rápida al código de Matcher.java
muestra un grupo de variables miembro que incluye el texto que se está emparejando, matrices para grupos, algunos índices para mantener la ubicación y algunos boolean
para otro estado. Todo esto apunta a un Matcher
estado que no se comportaría bien si se accede por múltiples Threads
. Lo mismo ocurre con Matchers :
Las instancias de esta clase no son seguras para su uso por múltiples hilos concurrentes.
Esto es solo un problema si, como @Bob Cross señala, usted hace todo lo posible para permitir el uso de su Matcher
en Matcher
separados. Si necesita hacer esto, y cree que la sincronización será un problema para su código, una opción que tiene es usar un objeto de almacenamiento ThreadLocal
para mantener un Matcher
por hilo de trabajo.
Seguridad de subprocesos con expresiones regulares en Java
RESUMEN:
La API de expresión regular de Java se ha diseñado para permitir que un patrón compilado individual se comparta en varias operaciones de coincidencia.
Puede llamar de forma segura a Pattern.matcher () en el mismo patrón desde diferentes subprocesos y usar las correspondencias de manera segura al mismo tiempo. Pattern.matcher () es seguro para construir emparejamientos sin sincronización. Aunque el método no está sincronizado, es interno a la clase Pattern, una variable volátil llamada compiled se establece siempre después de construir un patrón y leer al inicio de la llamada a matcher (). Esto fuerza a cualquier hilo que se refiera al Patrón a "ver" correctamente el contenido de ese objeto.
Por otro lado, no debe compartir un Matcher entre diferentes hilos. O al menos, si alguna vez lo hizo, debe usar la sincronización explícita.
Sí , de la documentación de la API de Java para la clase Pattern
Las instancias de esta clase (Patrón) son inmutables y son seguras para su uso por múltiples hilos concurrentes. Las instancias de la clase Matcher no son seguras para tal uso.
Si está buscando un código centrado en el rendimiento, intente restablecer la instancia de Matcher utilizando el método reset (), en lugar de crear instancias nuevas. Esto restablecería el estado de la instancia de Matcher, haciéndolo utilizable para la próxima operación de expresión regular. De hecho, es el estado mantenido en la instancia de Matcher el responsable de que no sea seguro para el acceso simultáneo.