O ile wiem, że java.util.Date
jest zmienna, więc nie jest wątek bezpieczne, jeśli wiele wątków próbowało uzyskać dostęp i modyfikowanie go. W jaki sposób wykorzystujemy blokowanie po stronie klienta lub kompozycję (opakowanie), aby zapewnić bezpieczeństwo wątków?Jak zrobić Java.util.Date wątku bezpieczny
Odpowiedz
w tej kolejności od najlepszego do najgorszego:
nie używać go w ogóle, sprawdź jodatime
nie używać go w ogóle używać
AtomicLong
lub niezmienna prymitywnylong
zvolatile
do reprezentowania czas epokiKapsuł go. Zawsze zwracaj kopię defensywną
Date
, nigdy nie odwołując się do obiektu wewnętrznegoWykonaj synchronizację na instancji .
Zastanawiam się, dlaczego uważasz, że 2. jest lepszy od trzeciego? – peter
@ user1389813: Dobre pytanie! 1. Prymitywy są niezmienne, a więc niejawnie wątkowo bezpieczne. 2. Nie można, przez przypadek, zwrócić odniesienia do obiektu wewnętrznego, a nie do kopii obronnej. 3. Więcej lekki, mniej kopiowania (naprawdę nie jest wielka sprawa). Jednak zgadzam się, że 2 i 3 są całkiem dobre. Również oczywiście "Date" ma lepszą semantykę niż "long". –
Rozumiem. Drugi punkt, którego potrzebujesz, aby go chronić przy użyciu blokady? jak @dystroy wskazał, że operacja inkrementacji nie jest atomowa. – peter
Nie ma prostego rozwiązania do tworzenia bezpiecznej dla wątków klasy Date
. Najlepszym sposobem jest zsynchronizowanie wszystkich sposobów użycia obiektów za pomocą bloków synchronized
.
Następnie musisz nosić ten blok synchronizacji, gdziekolwiek go użyjesz. Czy nie jest to dobre w praktyce? – peter
To okropne w kodzie. Dlatego odpowiedź Tomasza jest znacznie lepsza niż moja;) –
Najprostszym rozwiązaniem jest nigdy nie modyfikować daty i nigdy jej nie udostępniać. tj. używaj tylko daty dla zmiennych lokalnych.
Możesz używać JodaTime, ponieważ ma on niezmienne obiekty daty.
Możesz użyć wartości długiej (milisekund od epoki) zamiast instancji Date. Przypisanie jej będzie operacją atomową i zawsze będzie spójne.
Ale Twój problem może nie dotyczy samej wartości daty, ale całego algorytmu, co oznacza, że prawdziwa odpowiedź byłaby oparta na twoim prawdziwym problemie.
Oto przykład działania buggy w wielowątkowego kontekstu:
long time;
void add(long duration) {
time += duration;
}
Problemem jest to, że można mieć dwa dodatki równolegle wynikające tylko jeden skuteczny Ponadto, ponieważ time += duration
nie jest atomowy (to naprawdę time=time+duration
).
Używanie długiego zamiast zmiennego obiektu nie jest wystarczające. W takim przypadku można rozwiązać problem, ustawiając funkcję jako zsynchronizowaną, ale inne przypadki mogą być trudniejsze.
Co masz na myśli mówiąc: "Twój problem może nie dotyczy samej wartości danych, ale całego algorytmu – peter
Jeśli" rób ponownie długą operację rozpoczynając od odczytania daty i kończąc, zastępując wartość. Blokowanie wartości podczas operacji może to zrobić. –
czy to pomoże, jeśli sprawi, że będzie niestabilny? – peter
- 1. Lista kontrolna bezpieczny wątku java na AppEngine
- 2. Serializing java.util.Date
- 3. Zapisywanie do pliku w sposób bezpieczny dla wątku
- 4. Czy obiekt Session z wątku biblioteki zapytań Pythona jest bezpieczny?
- 5. Czy Parallel.ForEach w ConcurrentBag <T> bezpieczny wątku
- 6. Java: testowanie dostępu wątek na „nie wątku bezpieczny” metod
- 7. Jak długo bezpieczny, bezpieczny kanał TCP jest bezpieczny?
- 8. Czy jest to bezpieczny sposób inicjowania wątku [ThreadStatic]?
- 9. wątku bezpieczny sposób do komina danych z wielu procedur
- 10. Inteligentne rozwiązanie do przechowywania danych XML wątku bezpieczny z Boost,
- 11. Czy poniższy kod wątku inkrementującego jest bezpieczny w java?
- 12. Czy bezpieczny wątek SecureRandom jest bezpieczny?
- 13. GWT java.util.Date błąd serializacji
- 14. Alternatywna metoda setHours() java.util.Date?
- 15. jest + = w wątku wątku bezpieczne?
- 16. Personalizacja WSDL: XMLGregorianCalender na java.util.Date
- 17. Uzyskaj średnią z dwóch java.util.Date
- 18. Jak zapewnić bezpieczeństwo wątku użytecznej metody statycznej?
- 19. Jak utworzyć zmienną statyczną wątek bezpieczny
- 20. Jak przekonwertować Joda-Time DateTime na java.util.Date i na odwrót?
- 21. Czy wątek libuv jest bezpieczny?
- 22. Get java.util.Date się z Joda-Time DateTime
- 23. JSON `date (...)` to `java.Util.Date` using` org.json`
- 24. JavaScript Data i java.util.Date argument konstruktora
- 25. Jaka jest domyślna strefa czasowa w java.util.Date
- 26. Jak zrobić miganie elipsy?
- 27. Delphi - czy wątek TClientDataset jest bezpieczny?
- 28. Prosta konwersja między java.util.Date i XMLGregorianCalendar
- 29. Bezpiecznie konwertować Java.sql.date na Java.util.date przez rzutowanie?
- 30. Dlaczego większość metod java.util.Date jest przestarzała?
Jeśli już tu jesteśmy, 'GregorianCalendar' i' SimpleDateFormat' również nie są wątkami. Zawsze warto o tym pamiętać. –
Dzięki za przypomnienie – peter