Is Java Regex Thread safe?

I have a function that uses Pattern.compile and Matcher to find a list of strings for a pattern. This function is used in multiple threads. Each stream will have a unique template passed to the Pattern.compile template when creating the stream. The number of threads and patterns is dynamic, which means that during configuration I can add more patterns and threads.

Does this function need to be "synchronized" if it uses a regular expression? Is regex in java thread safe?

TIA

+83
java multithreading regex
Sep 01 '09 at 1:04
source share
5 answers

Yes , from the Java API documentation for the Template Class

Instances of this (Pattern) class are immutable and safe for use by multiple parallel threads. Matcher instances are unsafe for this use.

If you look at performance-oriented code, try resetting the Matcher instance using the reset () method instead of creating new instances. This will reset the state of the Matcher instance, making it suitable for the next regex operation. In fact, this state, supported by the Matcher instance, is responsible for the insecurity for simultaneous access.

+106
Sep 01 '09 at 1:14
source share

Java regex flow security

SUMMARY:

The Java Regular Expression API has been designed to allow a compiled template to share multiple match operations.

You can safely call Pattern.matcher () on the same pattern from different threads and use matches at the same time safely. Pattern.matcher () is safe to create matches without synchronization. Although the method is not synchronized, internally the Template Class, the compiled mutable variable is always set after the template is built and read at the beginning of the match () call . This forces any thread to reference the Template in order to correctly "see" the contents of this object.

On the other hand, you should not share matches between different streams. Or at least if you have ever done this, you should use explicit synchronization.

+8
Sep 01 '09 at 1:14
source share

Although you need to remember that thread safety should also take into account the surrounding code, it seems to you that you are lucky. The fact that Matchers are created using the matcher factory template and the lack of public constructors is a positive sign. Similarly, you use the static compile method to create an encompassing Pattern .

So, in a word, if you are doing something like an example:

Pattern p = Pattern.compile("a*b"); Matcher m = p.matcher("aaaaab"); boolean b = m.matches(); 

you should be doing pretty well.

The sequence of actions on the sample code for clarity: note that this example strongly means that the Matcher created in this way is local to the flow with the template and test. Ie, you should not expose Matcher this way for any other threads.

Honestly, this is the risk of any thread safety issue. The reality is that any code can be made unsafe if you try hard enough. Fortunately, there is a wonderful book that teaches us a number of ways that we could ruin our code. If we avoid these errors, we greatly reduce our likelihood of slicing problems.

+3
Sep 01 '09 at 1:11
source share

A quick look at the code for Matcher.java shows a bunch of member variables, including consistent text, arrays for groups, several indexes to support the location, and several boolean for another state. All of this indicates a Matcher state that will not behave well if multiple Threads . So JavaDoc :

Instances of this class are unsafe for use by multiple parallel threads.

This is only a problem if, as @Bob Cross points out, you are avoiding your path to allow the use of Matcher in a separate Thread s. If you need to do this, and you think that synchronization will be a problem for your code, you can use the ThreadLocal storage object to maintain the Matcher for the worker thread.

+2
Sep 01 '09 at 2:01
source share

To summarize, you can reuse (store in static variables) the compiled patterns and tell them to give you new Matches, when necessary, to test these regular expressions against a certain string

 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(); } } 

see http://zoomicon.wordpress.com/2012/06/01/validating-e-mails-using-regular-expressions-in-java/ (near the end) for the RegEx template used above to check email ( in case it doesnโ€™t fit you need to check your email, because they are published here)

+2
Jun 01 2018-12-12T00:
source share



All Articles