W programach wielowątkowych często może dojść do sytuacji, w której wiele wątków próbuje uzyskać dostęp do tych samych zasobów, co ostatecznie daje błędne i nieprzewidziane rezultaty.
Dlaczego warto korzystać z synchronizacji Java?
Synchronizacja Java służy do zapewnienia, za pomocą jakiejś metody synchronizacji, że tylko jeden wątek może uzyskać dostęp do zasobu w danym momencie.
samouczek javafx
Zsynchronizowane bloki Java
Java umożliwia tworzenie wątków i synchronizację ich zadań za pomocą zsynchronizowanych bloków.
Zsynchronizowany blok w Javie jest synchronizowany z jakimś obiektem. Wszystkie zsynchronizowane bloki synchronizują się na tym samym obiekcie i jednocześnie może być w nich wykonywany tylko jeden wątek. Wszystkie inne wątki próbujące wejść do zsynchronizowanego bloku są blokowane do czasu, aż wątek znajdujący się w zsynchronizowanym bloku opuści blok.
Notatka: Zsynchronizowane bloki w Javie są oznaczone słowem kluczowym synchronized.
Ogólna postać bloku synchronicznego
// Only one thread can execute at a time. // sync_object is a reference to an object // whose lock associates with the monitor . // The code is said to be synchronized on // the monitor object synchronized(sync_object) { // Access shared variables and other // shared resources }> Ta synchronizacja jest zaimplementowana w Javie za pomocą koncepcji zwanej monitorami lub blokadami. W danym momencie tylko jeden wątek może być właścicielem monitora. Kiedy wątek zostaje zablokowany, mówi się, że dostał się do monitora. Wszystkie inne wątki próbujące wejść na zablokowany monitor zostaną zawieszone do czasu opuszczenia monitora przez pierwszy wątek.
Rodzaje synchronizacji
Istnieją dwie synchronizacje w Javie wymienione poniżej:
- Synchronizacja procesów
- Synchronizacja wątków
1. Synchronizacja procesów w Javie
Synchronizacja procesów to technika używana do koordynowania wykonywania wielu procesów. Dba o to, aby wspólne zasoby były bezpieczne i uporządkowane.
2. Synchronizacja wątków w Javie
Synchronizacja wątków służy do koordynowania i porządkowania wykonywania wątków w programie wielowątkowym. Poniżej wymieniono dwa typy synchronizacji wątków:
- Wzajemna wyłączność
- Współpraca (komunikacja międzywątkowa w Javie)
Wzajemna wyłączność
Funkcja Mutual Exclusive pomaga zapobiegać wzajemnemu zakłócaniu się wątków podczas udostępniania danych. Istnieją trzy rodzaje wzajemnej wyłączności wymienione poniżej:
- Metoda zsynchronizowana.
- Zsynchronizowany blok.
- Synchronizacja statyczna.
Przykład synchronizacji
Poniżej znajduje się implementacja synchronizacji Java:
Jawa
ile miast w stanach zjednoczonych ameryki
wiek Ankity Lokhande
// A Java program to demonstrate working of> // synchronized.> import> java.io.*;> import> java.util.*;> // A Class used to send a message> class> Sender {> >public> void> send(String msg)> >{> >System.out.println(>'Sending '> + msg);> >try> {> >Thread.sleep(>1000>);> >}> >catch> (Exception e) {> >System.out.println(>'Thread interrupted.'>);> >}> >System.out.println(>'
'> + msg +>'Sent'>);> >}> }> // Class for send a message using Threads> class> ThreadedSend>extends> Thread {> >private> String msg;> >Sender sender;> >// Receives a message object and a string> >// message to be sent> >ThreadedSend(String m, Sender obj)> >{> >msg = m;> >sender = obj;> >}> >public> void> run()> >{> >// Only one thread can send a message> >// at a time.> >synchronized> (sender)> >{> >// synchronizing the send object> >sender.send(msg);> >}> >}> }> // Driver class> class> SyncDemo {> >public> static> void> main(String args[])> >{> >Sender send =>new> Sender();> >ThreadedSend S1 =>new> ThreadedSend(>' Hi '>, send);> >ThreadedSend S2 =>new> ThreadedSend(>' Bye '>, send);> >// Start two threads of ThreadedSend type> >S1.start();> >S2.start();> >// wait for threads to end> >try> {> >S1.join();> >S2.join();> >}> >catch> (Exception e) {> >System.out.println(>'Interrupted'>);> >}> >}> }> |
>
>Wyjście
Sending Hi Hi Sent Sending Bye Bye Sent>
Wynik jest taki sam za każdym razem, gdy uruchamiamy program.
Wyjaśnienie
W powyższym przykładzie wybieramy synchronizację obiektu Sender wewnątrz metody run() klasy ThreadedSend. Alternatywnie moglibyśmy zdefiniować cały blok send() jako zsynchronizowany , dając ten sam rezultat. Nie musimy wtedy synchronizować obiektu Message wewnątrz metody run() w klasie ThreadedSend.
// An alternate implementation to demonstrate // that we can use synchronized with method also. class Sender { public synchronized void send(String msg) { System.out.println('Sending ' + msg); try { Thread.sleep(1000); } catch (Exception e) { System.out.println('Thread interrupted.'); } System.out.println('
' + msg + 'Sent'); } }> Nie zawsze musimy synchronizować całą metodę. Czasem lepiej synchronizować tylko część metody . Umożliwiają to synchronizowane bloki Java wewnątrz metod.
maszyna skończona
// One more alternate implementation to demonstrate // that synchronized can be used with only a part of // method class Sender { public void send(String msg) { synchronized(this) { System.out.println('Sending ' + msg ); try { Thread.sleep(1000); } catch (Exception e) { System.out.println('Thread interrupted.'); } System.out.println('
' + msg + 'Sent'); } } }> Przykład metody synchronized przy użyciu klasy anonimowej
Jawa
system plików Linuksa
// Java Pogram to synchronized method by> // using an anonymous class> import> java.io.*;> class> Test {> >synchronized> void> test_function(>int> n)> >{> >// synchronized method> >for> (>int> i =>1>; i <=>3>; i++) {> >System.out.println(n + i);> >try> {> >Thread.sleep(>500>);> >}> >catch> (Exception e) {> >System.out.println(e);> >}> >}> >}> }> // Driver Class> public> class> GFG {> >// Main function> >public> static> void> main(String args[])> >{> >// only one object> >final> Test obj =>new> Test();> >Thread a =>new> Thread() {> >public> void> run() { obj.test_function(>15>); }> >};> >Thread b =>new> Thread() {> >public> void> run() { obj.test_function(>30>); }> >};> >a.start();> >b.start();> >}> }> |
>
>Wyjście
16 17 18 31 32 33>