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