2012-12-17 20 views
35

Czy istnieje jakikolwiek ogólny sposób lub reguły wyjścia, dzięki którym możemy zapewnić bezpieczeństwo wątków metod statycznych używanych w różnych klasach użytkowych dla dowolnych aplikacji. Tutaj chcę wyraźnie wskazać bezpieczeństwo wątków aplikacji internetowych.Jak zapewnić bezpieczeństwo wątku użytecznej metody statycznej?

Dobrze wiadomo, że statyczne metody z niezmiennymi obiektami jako parametrami są bezpieczne dla wątków, a obiekty z możliwością mutowania nie.

Jeśli mam metodę użytkową do pewnego manipulowania java.util.Date i ta metoda akceptuje instancję java.util.Date, to ta metoda nie byłaby bezpieczna dla wątków. Jak zabezpieczyć wątek bez zmiany sposobu przekazywania parametrów?

public class DateUtils { 

    public static Date getNormalizeDate(Date date) { 
     // some operations 
    } 
} 

Czy możliwa jest zmiana klasy javax.faces.context.FacesContext? Czy można bezpiecznie przesyłać instancję tej klasy do takiej statycznej metody użyteczności?

Ta lista klas, których wystąpienia mogą być lub nie mogą być przekazane jako parametry, może być długa; więc o jakich punktach powinniśmy pamiętać podczas pisania kodów takich klas użytkowych?

+2

Dlaczego głosowanie i jedna bliska prośba? Czy to niewłaściwe pytanie? –

+0

Czy rozważałeś wykonanie tej statycznej metody 'zsynchronizowanej'? –

+6

@AndrewLogvinov tak, pomyślałem. Ale nie chcę synchronizować metody, nie wiedząc, dlaczego to robię. W jakich sytuacjach powinniśmy synchronizować statyczną metodę? –

Odpowiedz

46

Powszechnie wiadomo, że metody statyczne z niezmiennymi obiektami jako parametrami są bezpieczne dla wątków, a zmienne obiekty nie.

Podważałbym to. Argumenty przekazywane do metody są przechowywane na stosie, który jest idiomem na wątek.

Jeśli twój parametr jest obiektem zmiennym, takim jak Date, musisz upewnić się, że inne wątki nie modyfikują go w tym samym czasie w innym miejscu. Ale to inna sprawa niezwiązana z bezpieczeństwem wątku twojej metody.

Opublikowana przez ciebie metoda jest bezpieczna dla wątków. Nie utrzymuje stanu i działa tylko na swoich argumentach.

Gorąco polecam przeczytanie Java Concurrency in Practice lub podobnej książki poświęconej bezpieczeństwu wątków w języku Java. Jest to złożony temat, którego nie można rozwiązać właściwie za pomocą kilku odpowiedzi StackOverflow.

+0

Świetna odpowiedź, dzięki – Keerthivasan

3

Zalecam utworzenie kopii tego (zmiennego) obiektu zaraz po uruchomieniu metody i użycie kopii zamiast oryginalnego parametru.

coś takiego

public static Date getNormalizeDate(Date date) { 
    Date input = new Date(date.getTime()); 
    // ... 
} 
+2

To brzmi dobrze dla Date, ale nie będzie możliwe dla obiektów niestandardowych, zwłaszcza jeśli jest to niestandardowy obiekt innej firmy, którego nie może edytować. –

11

Ponieważ klasa nie posiada zmiennych składowych, metoda jest bezpaństwowcem (używa tylko zmienne lokalne i argument) i dlatego są bezpieczne dla wątków.

Kod, który wywołuje ten kod, może nie być bezpieczny dla wątków, ale to kolejna dyskusja. Na przykład Data nie jest bezpieczna dla wątków, jeśli kod wywołujący odczytuje datę, która została zapisana przez inny wątek, musisz użyć właściwej synchronizacji w kodzie zapisu i odczytu daty.

4

Biorąc pod uwagę strukturę JVM, zmienne lokalne, parametry metody i wartości zwracane są z natury "bezpieczne dla wątków". Ale zmienne instancji i zmienne klasy będą bezpieczne tylko dla wątków, jeśli odpowiednio zaprojektujesz klasę. więcej here

0

Oto, jak o tym myślę: wyobraź sobie CampSite (to metoda statyczna).Jako kamper mogę wnieść do plecaka kilka przedmiotów (to argumenty przekazywane na stosie). CampSite zapewnia mi miejsce do umieszczenia mojego namiotu i mojego campstovera itp., Ale jeśli jedyną rzeczą, którą CampSite robi, jest umożliwienie mi modyfikacji własnych obiektów, to jest to bezpieczne dla wątków. CampSite może nawet tworzyć rzeczy z powietrza (FirePit firepit = new FirePit();), które również są tworzone na stosie.

W każdej chwili mogę zniknąć z wszystkimi moimi przedmiotami w moim rumianku i jeden z innych obozowiczów może pojawić się, robiąc dokładnie to, co robili, gdy ostatni raz zniknęli. Różne wątki w tym CampSite nie będą miały dostępu do obiektów na stosie utworzonego CampSite w innych wątkach.

Powiedzmy, że istnieje tylko jeden campStove (pojedynczy obiekt CampStove, a nie oddzielne wystąpienia). Jeśli w jakimś fragmencie wyobraźni dzielę obiekt CampStove, to są rozważania wielowątkowe. Nie chcę włączać mojego campStove, znikać, a potem pojawiać się ponownie po wyłączeniu innego kampera - zawsze będę sprawdzać, czy mój hot dog został zrobiony i nigdy nie będzie. Musiałbyś umieścić gdzieś synchronizację ... w klasie CampStove, w metodzie, która wywoływała CampSite, lub w samym CampSite ... ale jak Duncan Jones mówi "to inna sprawa".

Należy pamiętać, że nawet jeśli biwakowalibyśmy w oddzielnych instancjach non -statycznych obiektów CampSite, współużytkowanie obiektu campStove miałoby tę samą wielowątkowość.

Powiązane problemy