Отменить длительный матч с регулярным выражением?
Скажем, у меня есть служба, где пользователи могут отправлять регулярные выражения для поиска по большому количеству данных. Если пользователь отправляет регулярное выражение очень медленно (т.е. Matcher.find () возвращает минуты), я хочу отменить это совпадение. Единственный способ, которым я могу думать об этом, - это иметь другой монитор потока, сколько времени занимает совпадение, и использовать Thread.stop (), чтобы отменить его, если это необходимо.
Переменные-члены:
long REGEX_TIMEOUT = 30000L;
Object lock = new Object();
boolean finished = false;
Thread matcherThread;
Сопоставление темы:
try {
matcherThread = Thread.currentThread();
// imagine code to start monitor thread is here
try {
matched = matcher.find();
} finally {
synchronized (lock) {
finished = true;
lock.notifyAll();
}
}
} catch (ThreadDeath td) {
// send angry message to client
// handle error without rethrowing td
}
Мониторинг потока:
synchronized (lock) {
while (! finished) {
try {
lock.wait(REGEX_TIMEOUT);
if (! finished) {
matcherThread.stop();
}
} catch (InterruptedException ex) {
// ignore, top level method in dedicated thread, etc..
}
}
}
Я прочитал java.sun.com/j2se/1.4.2/docs/guide/misc/threadPrimitiveDeprecation.html, и я думаю, что это использование безопасно, так как я контролирую, где ThreadDeath выбрасывается через синхронизацию, и обрабатываю его и только поврежденный объекты могут быть моими экземплярами Pattern и Matcher, которые все равно будут отброшены. Я думаю, что это нарушает Thread.stop (), потому что я не выкидываю ошибку, но я не хочу, чтобы поток умер, просто прервите метод find ().
До сих пор мне удавалось избегать использования этих устаревших компонентов API, но Matcher.find (), кажется, не прерываемый и может вернуться очень долго. Есть ли лучший способ сделать это?