Скажем, что я запускаю службу, где пользователи могут отправлять регулярное выражение для поиска по большому количеству данных. Если пользователь отправляет регулярное выражение, которое очень медленно (т.е. Для возвращения 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(), похоже, не прерывается и может занять очень много времени. Есть ли лучший способ сделать это?