Контейнер сервлетов имеет пул нитей (thread), которые он будет диспетчеризировать для обработки запросов клиентов. Они вполне подходят для случая, когда два клиентских запроса поступают одновременно и должны одновременно обработаться вашим методом service( ). Поэтому метод service( ) должен быть выполнен безопасным для многопоточности способом. Любой доступ к общим ресурсам (файлам, базам данных) должен быть гарантировано использоваться с ключевым словом synchronized.
Следующий простой пример помещает выражение synchronized вокруг метода нити slepp( ). Это блокирует все другие нити до тех пор, пока не пройдет указанное время (пять секунд). Когда будете тестировать, вы должны запустить несколько экземпляров браузера и обратится к этому сревлету настолько быстро, насколько вы способны - вы увидите, что каждый экземпляр браузера будет ожидать, пока не получит ответ.
//: c15:servlets:ThreadServlet.java
// {Depends: j2ee.jar}
import javax.servlet.*;
import javax.servlet.http.*;
import java.io.*;
public class ThreadServlet extends HttpServlet {
int i;
public void service(HttpServletRequest req, HttpServletResponse res)
throws IOException {
res.setContentType("text/html");
PrintWriter out = res.getWriter();
synchronized (this) {
try {
Thread.currentThread().sleep(5000);
}
catch (InterruptedException e) {
System.err.println("Interrupted");
}
}
out.print("<h1>Finished " + i++ + "</h1>");
out.close();
}
} // /:~
Также возможно синхронизировать весь сервлет, поместив ключевое слово synchronized перед методом service( ). Фактически, есть только одна причина использовать выражение synchronized, если есть критическая секция в ходе выполнения, которая может быть не выполнена. В этом случае, вы можете предотвратить накладные расходы на каждую синхронизацию в блоке с помощью использования выражения synchronized. С другой стороны, все нити все равно будут ожидать, так что вы можете точно так же синхронизировать весь метод.
← | Основа сервлета | Обработка сессий с помощью сервлетов | → |