Powiedz, że korzystam z usługi, w której użytkownicy mogą przesłać wyrażenie regularne w celu przeszukiwania dużej ilości danych. Jeśli użytkownik prześle wyrażenie, które jest bardzo powolne (tj. Wraca do zwrócenia Matcher.find() minut), chcę sposób na anulowanie tego dopasowania. Jedyny sposób, w jaki mogę to zrobić, to mieć inny wątek monitorujący, jak długo trwa mecz i użyć Thread.stop(), aby anulować, jeśli to konieczne.Anulowanie długo działającego dopasowania do wyrażenia regularnego?
zmienne użytkownika: gwint
long REGEX_TIMEOUT = 30000L;
Object lock = new Object();
boolean finished = false;
Thread matcherThread;
Matcher: gwint
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
}
Monitor:
synchronized (lock) {
while (! finished) {
try {
lock.wait(REGEX_TIMEOUT);
if (! finished) {
matcherThread.stop();
}
} catch (InterruptedException ex) {
// ignore, top level method in dedicated thread, etc..
}
}
}
Czytałem java.sun.com/j2se/1.4.2/ docs/guide/misc/threadPrimitiveDeprecation.html i myślę, że to użycie jest bezpieczne, ponieważ kontroluję, gdzie ThreadDeath jest generowany przez synchronizację i ha ndle go i jedynymi uszkodzonymi obiektami mogą być moje instancje Pattern i Matcher, które i tak zostaną odrzucone. Myślę, że to zrywa Thread.stop(), ponieważ nie przerzucam błędu, ale tak naprawdę nie chcę, aby wątek umarł, wystarczy przerwać metodę find().
Do tej pory udało mi się uniknąć używania tych nieaktualnych komponentów API, ale metoda Matcher.find() nie wydaje się być przerywana i może zająć bardzo dużo czasu. Czy istnieje lepszy sposób to zrobić?
Osobiście uważam, że zezwolenie użytkownikom na przesłanie wyrażenia regularnego jako kryterium wyszukiwania jest złym pomysłem. Programiści być może, ale nie końcowi użytkownicy ... –
Z pewnością powinieneś spodziewać się DoSed, jeśli zaakceptujesz arbitralne wyrażenia regularne. –
Nie wszystkie kody są narażone na działanie sieci publicznej, w której musisz się martwić o DoS. – Jared