Synckronizacija u Java
Što je Synckronizacija u Java?
In Java, sinkronizacija se odnosi na mogućnost kontrole pristupa više niti bilo kojem dijeljenom resursu. To je idealna opcija kada samo jednoj niti želimo dopustiti pristup dijeljenom resursu.
Ovaj pristup izvršenja obično se naziva `asinkrono` programiranje. Na ovim procesorima također postoje niti, koje su lagani procesi koji mogu izvršavati instrukcije istovremeno.
Vrste Synchroniziranje
Postoje dvije vrste metoda sinkronizacije Java:
1) Sinkronizacija procesa
2) Sinkronizacija niti.
Proučimo Thread i Sinkronizacija procesa detaljno.
Sinkronizacija procesa: Upravlja sinkronizacijom između programa. Na primjer, programi poput `Microsoft Word` i `Acrobat reader` pokreću se kao pojedinačni procesi.
Sinkronizacija niti: Istodobno izvršavanje kritičnog resursa od strane dvije ili više niti naziva se niti Synchroniziranje. Možete se dodatno grupirati u međusobno isključivu komunikaciju i komunikaciju između niti.
Što je Lock in Java?
Zaključati u Java izgrađen je oko unutarnjeg entiteta poznatog kao monitor ili brava. Svi objekti imaju povezanu bravu. Dakle, nit koja treba konzistentan pristup poljima objekta mora steći zaključavanje objekta prije nego što im pristupi, i otpušta zaključavanje kada je posao obavljen. Ovo osigurava da samo jedna nit istovremeno pristupa dijeljenim podacima.
Višenitni program sa sinkronizacijom
Višenitni program je metoda ili blok zaštićen od smetnji drugih niti koje dijele isti resurs naznačen pomoću ključne riječi `sinkronizirano`.
Korištenje sinkronizirane metode
Svaka metoda koja je deklarirana kao sinkronizirana poznata je kao sinkronizirana metoda. Također se koristi za zaključavanje objekta za bilo koji zajednički resurs. Dakle, kada nit pozove sinkroniziranu metodu. Automatski preuzima bravu za taj objekt i otpušta ga kada završi svoj zadatak.
Bilješka: Sinkronizirana ključna riječ ne može raditi s klasama i varijablama. Uz ključnu riječ mogu se koristiti samo metode i blokovi.
Zašto koristiti Synckronizirana metoda?
- Koristi se za zaključavanje objekta za bilo koje zajedničke resurse.
- Objekt dobiva zaključavanje kad god se pozove sinkronizirana metoda.
- Brava se ne otpušta sve dok nit ne završi svoju funkciju
Sintaksa:
Acess_modifiers synchronized return_type method_name (Method_Parameters) { }
class MathService { synchronized void getSumOfArray(int[] numbers) { int sum = 0; for (int number : numbers) { System.out.println(Thread.currentThread() .getName() + " adds " + sum + " to " + number + " to get -> " + (sum += number)); try { Thread.sleep(500); } catch (InterruptedException e) { throw new RuntimeException(e); } } } } public class Synchronization { public static void main(String[] args) { MathService mathService = new MathService(); Thread threadOne = new Thread(() -> mathService.getSumOfArray(new int[]{10, 11, 12})); Thread threadTwo = new Thread(() -> mathService.getSumOfArray(new int[]{20, 21, 22})); threadOne.start(); threadTwo.start(); } }
Objašnjenje koda:
Pokrenite ovaj primjer i promatrajte da nit `0` prvo dobiva zaključavanje objekta `mathService` i koristi to zaključavanje isključivo dok ne dovrši izvođenje. Niti "0" i "1" nisu isprepleteni u ovom kodu. Izlaz je kao što je prikazano u nastavku.
Izlaz:
Thread-0 adds 0 to 10 to get -> 10 Thread-0 adds 10 to 11 to get -> 21 Thread-0 adds 21 to 12 to get -> 33 Thread-1 adds 0 to 20 to get -> 20 Thread-1 adds 20 to 21 to get -> 41 Thread-1 adds 41 to 22 to get -> 63
Korištenje sinkroniziranog bloka
Pretpostavimo da ne želite sinkronizirati cijelu metodu. Umjesto toga, želite sinkronizirati nekoliko redaka koda. U to vrijeme, Synchronizirani blok pomogao sinkronizirati taj odabrani Java kodirati. Synczaključavanjima kroniziranih metoda pristupa se na metodi, dok se zaključavanjima sinkroniziranih blokova pristupa na objektu.
class MathService { void getSumOfArray(int[] numbers) { synchronized (this){ int sum = 0; for (int number : numbers) { System.out.println(Thread.currentThread() .getName() + " adds " + sum + " to " + number + " to get -> " + (sum += number)); try { Thread.sleep(500); } catch (InterruptedException e) { throw new RuntimeException(e); } } } } } public class Synchronization { public static void main(String[] args) { MathService mathService = new MathService(); Thread threadOne = new Thread(() -> mathService.getSumOfArray(new int[]{10, 11, 12})); Thread threadTwo = new Thread(() -> mathService.getSumOfArray(new int[]{20, 21, 22})); threadOne.start(); threadTwo.start(); } }
Objašnjenje koda:
Nakon pokretanja ovog koda primijetit ćete da radi bez ikakvih smetnji. U sinkroniziranoj metodi zaključavanje primjenjuje metoda, ali u sinkroniziranom bloku zaključavanje primjenjuje objekt. Provjerite je li izlaz kao što je prikazano u nastavku.
Izlaz:
Thread-0 adds 0 to 10 to get -> 10 Thread-0 adds 10 to 11 to get -> 21 Thread-0 adds 21 to 12 to get -> 33 Thread-1 adds 0 to 20 to get -> 20 Thread-1 adds 20 to 21 to get -> 41 Thread-1 adds 41 to 22 to get -> 63
Objašnjenje koda:
Kada pokrenete ovaj kod, primijetit ćete da radi bez smetnji, što smo i očekivali. U sinkroniziranoj metodi zaključavanje primjenjuje metoda, ali u metodi sinkroniziranog bloka zaključavanje primjenjuje objekt.
Korištenje statičke sinkronizacije
In Java sinkronizacija, ako postoji više od jednog objekta, dvije niti mogu dobiti zaključavanja i ući u sinkronizirani blok ili blok, s posebnim zaključavanjem za svaki objekt. Kako bi se to izbjeglo, može se koristiti statička sinkronizacija. Synckronizirane ključne riječi koristit će se prije statičkih metoda.
Bilješka: U statičkoj sinkronizaciji pristup zaključavanju je na klasi, a ne na objektu i metodi.
Kod za demonstraciju problema zaključavanja više objekata
class MathService { synchronized void getSumOfArray(int[] numbers) { int sum = 0; for (int number : numbers) { System.out.println(Thread.currentThread() .getName() + " adds " + sum + " to " + number + " to get -> " + (sum += number)); try { Thread.sleep(500); } catch (InterruptedException e) { throw new RuntimeException(e); } } } } public class Synchronization { public static void main(String[] args) { MathService mathService = new MathService(); MathService mathService1 = new MathService(); Thread threadOne = new Thread(() -> mathService.getSumOfArray(new int[]{10, 11, 12})); Thread threadTwo = new Thread(() -> mathService.getSumOfArray(new int[]{20, 21, 22})); Thread threadThree = new Thread(() -> mathService1.getSumOfArray(new int[]{10, 11, 12})); Thread threadFour = new Thread(() -> mathService1.getSumOfArray(new int[]{20, 21, 22})); threadOne.start(); threadTwo.start(); threadThree.start(); threadFour.start(); } }
Objašnjenje koda:
Kada stvorimo drugu instancu `MathService`, uvodimo smetnje u niti jer će biti isprepletene s dva objekta. Imajte na umu da su nit `0` i nit `2` isprepletene s dva objekta, dok su nit `1` i `3` isprepletene s dva objekta.
Izlaz:
Thread-0 adds 0 to 10 to get -> 10 Thread-2 adds 0 to 10 to get -> 10 Thread-0 adds 10 to 11 to get -> 21 Thread-2 adds 10 to 11 to get -> 21 Thread-0 adds 21 to 12 to get -> 33 Thread-2 adds 21 to 12 to get -> 33 Thread-1 adds 0 to 20 to get -> 20 Thread-3 adds 0 to 20 to get -> 20 Thread-1 adds 20 to 21 to get -> 41 Thread-3 adds 20 to 21 to get -> 41 Thread-1 adds 41 to 22 to get -> 63 Thread-3 adds 41 to 22 to get -> 63
Isti kod korištenjem sinkronizirane statičke metode
class MathService { synchronized static void getSumOfArray(int[] numbers) { int sum = 0; for (int number : numbers) { System.out.println(Thread.currentThread() .getName() + " adds " + sum + " to " + number + " to get -> " + (sum += number)); try { Thread.sleep(500); } catch (InterruptedException e) { throw new RuntimeException(e); } } } } public class Synchronization { public static void main(String[] args) { MathService mathService = new MathService(); MathService mathService1 = new MathService(); Thread threadOne = new Thread(() -> mathService.getSumOfArray(new int[]{10, 11, 12})); Thread threadTwo = new Thread(() -> mathService.getSumOfArray(new int[]{20, 21, 22})); Thread threadThree = new Thread(() -> mathService1.getSumOfArray(new int[]{10, 11, 12})); Thread threadFour = new Thread(() -> mathService1.getSumOfArray(new int[]{20, 21, 22})); threadOne.start(); threadTwo.start(); threadThree.start(); threadFour.start(); } }
Pokrenite gornji kod i imajte na umu da smo sada eliminirali smetnje niti. Izlaz koda prikazan je u nastavku.
Izlaz:
Thread-0 adds 0 to 10 to get -> 10 Thread-0 adds 10 to 11 to get -> 21 Thread-0 adds 21 to 12 to get -> 33 Thread-3 adds 0 to 20 to get -> 20 Thread-3 adds 20 to 21 to get -> 41 Thread-3 adds 41 to 22 to get -> 63 Thread-2 adds 0 to 10 to get -> 10 Thread-2 adds 10 to 11 to get -> 21 Thread-2 adds 21 to 12 to get -> 33 Thread-1 adds 0 to 20 to get -> 20 Thread-1 adds 20 to 21 to get -> 41 Thread-1 adds 41 to 22 to get -> 63
Prednosti korištenja sinkronizacije
Evo prednosti rada s istodobnim aplikacijama:
- Glavni cilj sinkronizacije u Java je spriječiti nedosljedne podatke sprječavanjem interferencije niti.
- Sinkronizirana ključna riječ u Java pruža zaključavanje, koje osigurava međusobno isključiv pristup dijeljenom resursu i sprječava utrku podataka.
- Također sprječava promjenu redoslijeda izraza koda od strane kompajler, što može uzrokovati suptilan istovremeni problem ako ne koristimo promjenjive ili sinkronizirane ključne riječi.
- Synchronizirana ključna riječ čita podatke iz glavne memorije nego iz predmemorije i kada otključa.
- Također ispire operacije pisanja iz glavne memorije, eliminirajući greške nedosljednosti memorije.
Nedostaci Syncmehanizam kronizacije
Synckronizacija Mehanizmi imaju slabu izvedbu.
Na primjer
- Pretpostavimo da postoji pet procesa, A1, A2, A3, A4 i A5.
- Oni čekaju da zajednički resursi pristupe jednoj po jednoj niti.
- Svi procesi ostaju na čekanju, tako da posljednji u redu čekanja moraju čekati dok se svi ostali procesi ne završe.
rezime
- Synchronizacija se odnosi na mogućnost kontrole pristupa više niti bilo kojem zajedničkom resursu.
- Java ima dvije vrste metoda sinkronizacije: 1) Sinkronizacija procesa i 2) Sinkronizacija niti.
- Zaključati u Java izgrađen je oko unutarnjeg entiteta poznatog kao monitor ili brava.
- Višenitni program je metoda ili blok zaštićen od smetnji drugih niti koje dijele isti resurs označen pomoću ključne riječi `sinkronizirano`.
- Svaka metoda koja je deklarirana kao sinkronizirana poznata je kao sinkronizirana metoda.
- In Java, zaključavanjima sinkroniziranih metoda pristupa se na metodi, dok se zaključavanjima sinkroniziranih blokova pristupa na objektu.
- U statičkoj sinkronizaciji pristup zaključavanju je na klasi, a ne na objektu i metodi.
- Glavni cilj sinkronizacije u Java je spriječiti nedosljedne podatke sprječavanjem interferencije niti.
- Najveći nedostatak ove metode je što se svi procesi drže na čekanju, tako da posljednji u redu čekanja moraju čekati dok se svi ostali procesi ne završe.