Computer >> บทช่วยสอนคอมพิวเตอร์ >  >> การเขียนโปรแกรม >> Java

Java Matcher Thread-Safe หรือไม่


Regular Expression คือลำดับตัวอักษรพิเศษกำหนด Pattern ใช้ค้นหา แก้ไข จัดการข้อความ Java มี java.util.regex package

Matcher Class

Matcher เป็น Engine ที่ตีความ Pattern และทำ Match Operations กับ Input String

  • ไม่มี public constructors
  • สร้างผ่าน Pattern.matcher(CharSequence)
⚠️ สำคัญ: Instances ของ Matcher Class ไม่ Thread-Safe
ไม่ควรใช้ Matcher instance เดียวกันจากหลาย Thread พร้อมกัน

ตัวอย่าง: หาสตริงที่ขึ้นต้นด้วยตัวเลข

import java.util.Scanner;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class StartingWithDigit {
    public static void main(String args[]) {
        String regex = "^[0-9].*$";  // เริ่มต้นด้วยตัวเลข
        
        Scanner sc = new Scanner(System.in);
        System.out.println("Enter 5 input strings: ");
        String[] input = new String[5];
        for (int i = 0; i < 5; i++) {
            input[i] = sc.nextLine();
        }
        
        Pattern p = Pattern.compile(regex);
        System.out.println("Strings starting with digits: ");
        
        for (int i = 0; i < 5; i++) {
            // สร้าง Matcher ใหม่ทุกครั้ง (Thread-safe way)
            Matcher m = p.matcher(input[i]);
            if (m.matches()) {
                System.out.println(m.group());
            }
        }
    }
}

Output

Enter 5 input strings: 
sample string 1
sample string 2
11 sample string 3
22 sample string 4
43534 56353 636

Strings starting with digits:
11 sample string 3
22 sample string 4
43534 56353 636

Thread-Safety Summary

ClassThread-Safeหมายเหตุ
Pattern✅ ใช่Immutable หลัง compile แล้ว ใช้ร่วมได้
Matcher❌ ไม่Mutable state (position, groups) - สร้างใหม่ทุก thread

Best Practice สำหรับ Multi-threaded

// ✅ ดี - Pattern shared, Matcher per-thread
public class RegexUtil {
    private static final Pattern EMAIL_PATTERN = Pattern.compile("^[\\w.+-]+@[\\w-]+\\.[\\w.-]+$");
    
    public static boolean isValidEmail(String email) {
        // สร้าง Matcher ใหม่ทุกครั้ง
        return EMAIL_PATTERN.matcher(email).matches();
    }
}

// หรือใช้ ThreadLocal (หากต้อง reuse Matcher - นادرة)
public class ThreadLocalMatcher {
    private static final Pattern PATTERN = Pattern.compile("...");
    private static final ThreadLocal MATCHER = ThreadLocal.withInitial(() -> PATTERN.matcher(""));
    
    public static boolean matches(String input) {
        Matcher m = MATCHER.get();
        m.reset(input);  // reset ด้วย input ใหม่
        return m.matches();
    }
}