2012-03-26 15 views
9

Rozumiem, że klasy działań Struts2 są wątkowo bezpieczne, ponieważ akcje są umieszczane w stosie wartości. Stos wartości jest z kolei częścią kontekstu działania. Ponieważ kontekst działania jest wątkiem lokalnym, wartości przechowywane w kontekście działania (w tym stos wartości) są unikalne dla każdego wątku. A więc Akcje są wątkowo bezpieczne.Czy interceptory są w Struts2 Thread Unsafe?

Uważaj jednak na przechwytywacze: są naprawdę użyteczne, wykonują wszystkie te żmudne zadania dla programisty ... jak sprawdzanie poprawności, pobieranie wartości paramicznych itp. Ale należy wziąć pod uwagę, że: Interceptory mogą być dzielone między wiele próśb. Czy to powoduje, że przechwytywanie wątków jest niebezpieczne?

Z tym pytaniem próbowałem surfować po sieci w poszukiwaniu dobrych artykułów związanych z tym problemem. I znalazłem bardzo dobry artykuł, o którym wyraźnie wspomniałem w przykładzie Jak interceptory NIE są bezpieczne dla wątków.

strona internetowa jest: http://www.bullraider.com/java/struts2/tutorials/interceptors-and-thread-safety

Co muszę wiedzieć z tego artykułu jest głównym powodem przechwytujących będących wątek un-bezpieczne jest to, że kolektory są tworzone tylko raz. tj. każdy przechwytujący ma tylko jeden obiekt. Tak więc pola instancji nie są bezpieczne, gdy to samo wystąpienie obiektu przechwytującego jest współużytkowane przez wątki.

Na końcu artykułu wspomniano, że są przypadki, w których nawet przechwytujące są bezpieczne dla wątków. Ale nie wspomnieli o takich przypadkach. Przeszukałem sieć, aby znaleźć odpowiedź ... ale na próżno :(

Czy ktoś może mi powiedzieć lub podać mi link, gdzie mogę dowiedzieć się, jak sprawić, aby przechwytujące były wątkowane (lub jakie są scenariusze gdy Interceptor jest bezpieczne dla wątków)

Odpowiedz

13

Wszelkie Interceptor że nie używa pól instancji lub inny stan dzielone jest bezpieczny wątku:

Dla przykładów, spójrz na all the built-in interceptors że analizowania parametrów żądania HTTP i ciasteczka, rejestrowanie, sprawdzanie dostępu, obsługa wyjątków: nie używają pól instancji dla stanu zmiennego (*), ale tylko op wygasają na instancji ActionInvocation, które otrzymują jako parametry.

(*) niektórzy mają instancji pola dla parametrów konfiguracyjnych, które są ustawiane gdy Struts uruchamia się (w jednym wątku), jak ExceptionMappingInterceptor lub wątku bezpieczny instancji pola lubią Logger w LoggingInterceptor.

Jeśli planujesz napisać własną Interceptor, pracuj tylko za pomocą parametru ActionInvocation, który zostanie przekazany, oraz zmiennych lokalnych w metodzie intercept(). Unikaj pokusy zrobienia metody przechwytywania lub wstawiania do bloku - stworzy to wąskie gardło w przypadku podejścia pojedynczych instancji Struts do przechwytujących.

Aby odpowiedzieć na pytania z komentarzy:

(1) Jak to się stało utworzenia wystąpienia działań dla każdego wątku nie wpływa na wydajność lub robi?

W przypadku nowoczesnych maszyn JVM koszt utworzenia obiektu jest znikomy. Nie powinno być zauważalnego wpływu na wydajność, jeśli zachowasz lekkie działanie, unikając kosztownej inicjalizacji, np.nie tworząc połączeń bazy danych wewnątrz akcji, ale używając puli połączeń.

(2) Czy u zaleca, aby nigdy nie używać domyślnego przechwytywania stos, i zawsze używać niestandardowych przechwytywania stos (gdzie wszystkie niewykorzystane przechwytujące, które używają zmiennych instancji) są usuwane tak, że będzie to bezpieczne dla wątków?

Nie sądzę, że żaden z domyślnych przechwytywaczy, które są dostarczane i skonfigurowane z wykorzystaniem Struts 2, nie jest bezpieczny dla wątków; nawet jeśli używają pól instancji (ponieważ są one używane tylko do konfiguracji lub same w sobie jako bezpieczne dla wątków, takie jak Logger).

Z mojego osobistego doświadczenia, należy tylko dotknąć/zmienić stos przechwytywacza, jeśli masz ku temu dobry powód (bezpieczeństwo gwintów wbudowanych przechwytujących nie jest jedno). Wiele rzeczy zachowuje się/pęka w nieoczekiwany sposób, jeśli zmienisz stosy - uruchamianie jednego z wbudowanych stosów, takich jak "default" lub "paramPrepareParam", oszczędza wiele frustracji na dłuższą metę. Dodanie własnych niestandardowych przechwytujących jest zwykle mniej uciążliwe niż usuwanie/zmiana rozmieszczenia przechwytujących z istniejącego stosu.

+2

+1 do dzielenia się tak wiele nieznanych rzeczy :) – tusar

+0

Dzięki. odpowiedź bardzo pouczająca. 2 pytania dla u: (1) Podkreśliliście bardzo dobrze, że umieszczanie metod przechwytywania w zsynchronizowanym bloku jest bardzo nieefektywne. Dlaczego tworzenie instancji akcji dla każdego wątku nie ma wpływu na wydajność? (2) Czy NIGDY nie zaleca się używania domyślnego stosu przechwytującego i zawsze stosu niestandardowego przechwytywacza (w którym wszystkie nieużywane przechwytywacze, które używają zmiennych instancji są usuwane), aby był bezpieczny dla wątków? –

+0

@BimanTripathy Dodałem moje zdanie na temat dwóch pytań do odpowiedzi. Proszę spojrzeć :) –