2014-12-25 4 views
1

Что нужно сделать, чтобы вручную остановить Servlet как вызов destroy, не помогает, если все потоки не вышли из службы.Остановить сервлет

Скажите, если у меня есть n количество сервлетов, и я хочу остановить только один из них.

+1

Почему вы хотите это сделать? В зависимости от вашей конечной цели может быть лучше просто отключить нормальную функциональность сервлета (т. Е. Преобразовать его в NOP) вместо отключения самого сервлета. – abl

ответ

1

Это поведение очень важно при работе с сервлетами. Экземпляры могут создаваться после многопоточной модели и, таким образом, не являются потокобезопасными.

Контейнер не позволяет нить вызывать метод service после того, как был вызван destroy.

Это дает вам возможность закрыть все ресурсы, которые использует ваш сервлет (db, файл, память и т. Д.).

@WebServlet 
public class OncePerApplicationServlet extends HttpServlet { 

private Connection connection; 

@Override 
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { 
    if(req.getParameter("closeServlet").equals("true")) 
     this.destroy(); 
    else 
     this.service(req, resp); // normal flow 
} 

// this method will never be called by the container after the destroy method has been invoked 
@Override 
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { 
    // 1. 
    try { 
     connection = DriverManager.getConnection("someDbUrl"); 
     Statement stm = connection.createStatement(); 
     stm.execute("select * from someTable"); 
    } catch (SQLException e) { 
     e.printStackTrace(); 
    } 
} 

@Override 
public void destroy() { 
    // the point is that when this method is called you should be able to 
    // clean up and close all resources, you can rest assured that there are no "loose" 
    // threads that need the connection-instance 
    try { 
     connection.close(); 
    } catch (SQLException e) { 
     e.printStackTrace(); 
    } 
} 
} 

Вот цитата из API-документации:

Этот интерфейс определяет методы для инициализации сервлета, чтобы обслуживать запросы, и удалить сервлет с сервера. Они известны как методы жизненного цикла и вызываются в следующей последовательности:

Сервлет построен, а затем инициализирован методом init. Любые обращаются с клиентами к методу службы. Сервлет выведен из эксплуатации, затем уничтожен методом уничтожения, затем сбор мусора и финализация. |

Link to the documentation

Успехов!

+0

Я стою исправлены. Они не одиночные. Но в многопоточной модели могут быть несколько экземпляров сервлета, созданных контейнером. Таким образом, программист должен сделать код потокобезопасным. В однопоточной модели каждый запрос обрабатывается последовательно. – thomas77

+1

Сервлеты являются одиночными. Только один экземпляр сервлета может существовать во всем жизненном цикле webapp. В этот экземпляр можно получить доступ к моим многопоточным потокам, следовательно, нужен потокобезопасный код. Отличное объяснение: [Как работают сервлеты? Instantiation, переменные сеанса и многопоточность] (http://stackoverflow.com/questions/3106452/how-do-servlets-work-instantiation-session-variables-and-multithreading) – abl

+0

Итак, вы имеете в виду, что его невозможно остановить сервлет вручную. ASFAIK, вызывающий destroy() в программе, не поможет остановить сервлет принудительно, пока он не будет выполнен с правильной услугой. Чтобы уточнить, этот вопрос задан в одном из интервью, поэтому мне интересно узнать, как это можно сделать? – Charu

Смежные вопросы