2010-02-10 17 views

Odpowiedz

21

Fakt: Jest tylko 1 instancja serwletu w webapp-tych dożywotni. Powstaje na starcie aplikacji webapp i zostaje zniszczony po zamknięciu aplikacji internetowej. Zobacz także this answer dla interpretacji zgrubnej.

W ten sposób została udostępniona wszystkim żądaniom (wątkom). Jeśli przypiszesz dane żądania lub dane o ograniczonej sesji jako instancję (lub jeszcze gorzej, jako zmienną static), to z pewnością nie jest ona bezpieczna dla wątków, ponieważ została następnie udostępniona wszystkim aplikacjom (wątkom) od wszystkich użytkowników (sesji) w całym serwisie. Wystarczy przypisać je jako zmienne lokalne metody, aby zachować ich bezpieczeństwo. Więc:

public class MyServlet extends HttpServlet { 

    private Object thisIsNOTThreadSafe; 

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { 
     Object thisIsThreadSafe; 

     thisIsNOTThreadSafe = request.getParameter("foo"); // BAD!! Shared among all requests! 
     thisIsThreadSafe = request.getParameter("foo"); // OK, this is thread safe. 
    } 
} 

To w zasadzie wszystko, co trzeba wziąć pod uwagę przy opracowywaniu serwletów z threadsafety w umyśle.

Następnie istnieją atrybuty sesji (HttpSession), które mogą być współużytkowane przez wiele żądań od tego samego użytkownika, ale w rzeczywistości nie trzeba się martwić synchronizowaniem dostępu do sesji. Zwykle umieszczasz tam tylko dane specyficzne dla użytkownika, takie jak zalogowany użytkownik, preferencje użytkownika, koszyk zakupów itp. Musisz tylko upewnić się, że nie wprowadzasz danych o czystym zasięgu w zakresie sesji. Zostałaby odzwierciedlona w wielu oknach/zakładkach przeglądarki wewnątrz tej samej sesji.

Następnie są atrybuty aplikacji (ServletContext), które są udostępniane wszystkim użytkownikom na całym świecie, ale zwykle dodaje się tam tylko stałe i inne dane statyczne, takie jak konfiguracja webapp, fabryka DAO, zawartość listy rozwijanej itp.To wszystko można przy okazji zrobić z ServletContextListener, patrz także podstawowy przykład na stronie this answer. Trzeba tylko upewnić się, że nie umieszczasz czystych danych o zakresie żądania lub sesji w zakresie aplikacji.

+0

Jedno pytanie dotyczące "jednego serwletu w życiu aplikacji internetowej" - Myślałem, że to obiekt połączony, więc tam * może * być więcej niż jeden według uznania serwletu w zależności od obciążenia. Czy to nie prawda? – duffymo

+0

Tylko jeśli implementuje (zgodnie z serwletem 2.4 przestarzałe) 'SingleThreadModel'. – BalusC

+0

@BalusC: Dziękuję bardzo Panie, ta odpowiedź pomogła mi w końcu. Usunąłem moje pytanie i przegłosowałem twoją odpowiedź. Nie ma nikogo takiego jak ty w Javie. Jeszcze raz dziękuję za milion. –

0

Masz na myśli w kontekście, w przeciwieństwie do innych aplikacji java? Naprawdę nie ma dużej różnicy. Każde żądanie do serwletu powoduje, że kontener wydaje nowy wątek do obsługi, więc zmienne instancji w serwlecie muszą być wątkowo bezpieczne. Lepiej radzić sobie z całym bizem ze zmiennymi lokalnymi w metodach doGet/doPost(). Jest jedna myśl, którą mogę wymyślić. W przypadku zmiennych sesji może się zdarzyć, że użytkownik ma otwarte dwa okna przeglądarki, oba kierujące do aplikacji. W takim przypadku należy również zwrócić uwagę na bezpieczeństwo nici z zakresem sesji.

1

Wow, to naładowane pytanie.

Mówiąc prościej, należy się upewnić, że dostęp do wszystkich współdzielonych danych jest dokładnie zsynchronizowany. Np. Możesz chcieć zsynchronizować dostęp do zmiennej statycznej za pomocą muteksu lub funkcji zsynchronizowanej.

Należy pamiętać, że w przypadku transakcji atomowych, które modyfikują wiele współdzielonych zasobów w tym samym czasie, konieczna może być synchronizacja na wyższych poziomach.

Projektowanie aplikacji współbieżnej nie jest proste i nie ma magicznej kuli (niestety). Gorąco polecam książkę "Java Concurrency in Practice", aby uzyskać więcej informacji na temat pisania bezpiecznego kodu współbieżnego.

16
+2

Wydaje mi się, że pozycja 4 w znacznym stopniu wyprzedza (obejmuje) 1-3. :) –

+3

cóż, potrzebna jest pewna podstawowa wiedza, zanim będzie można dokonać dobrego myślenia – Bozho

+0

+1 dla pozycji 4 :) – BalusC

Powiązane problemy