logo

Синхронізація в Java

Багатопотокові програми часто можуть стикатися з ситуацією, коли кілька потоків намагаються отримати доступ до тих самих ресурсів і, зрештою, дають помилкові та непередбачені результати.

Навіщо використовувати синхронізацію Java?

Синхронізація Java використовується, щоб певним методом синхронізації переконатися, що лише один потік може отримати доступ до ресурсу в певний момент часу.

xor c++

Синхронізовані блоки Java

Java надає спосіб створення потоків і синхронізації їхніх завдань за допомогою синхронізованих блоків.



Синхронізований блок в Java синхронізується на якомусь об'єкті. Усі синхронізовані блоки синхронізуються на одному об’єкті, і в них одночасно може виконуватися лише один потік. Усі інші потоки, які намагаються увійти до синхронізованого блоку, блокуються, доки потік усередині синхронізованого блоку не вийде з блоку.

Примітка: Синхронізовані блоки в Java позначаються ключовим словом synchronized.

Загальна форма синхронізованого блоку

// 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 }>

Ця синхронізація реалізована в Java за допомогою концепції, яка називається моніторами або замками. Тільки один потік може володіти монітором в певний момент часу. Коли потік отримує блокування, кажуть, що він увійшов до монітора. Усі інші потоки, які намагаються увійти до заблокованого монітора, будуть призупинені, доки перший потік не вийде з монітора.

Види синхронізації

Існує дві синхронізації в Java, згадані нижче:

  1. Синхронізація процесів
  2. Синхронізація потоків

1. Синхронізація процесів у Java

Синхронізація процесів — це техніка, яка використовується для координації виконання кількох процесів. Це гарантує безпеку та порядок спільних ресурсів.

2. Синхронізація потоків у Java

Синхронізація потоків використовується для координації та впорядкування виконання потоків у багатопотоковій програмі. Нижче згадано два типи синхронізації потоків:

  • Взаємне виключення
  • Співпраця (міжпотокове спілкування в Java)

Взаємне виключення

Mutual Exclusive допомагає уберегти потоки від перешкод один одному під час обміну даними. Нижче наведено три типи взаємного виключення:

  • Синхронізований метод.
  • Синхронізований блок.
  • Статична синхронізація.

Приклад синхронізації

Нижче наведено реалізацію синхронізації Java:

Java

python зменшити




// 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'>);> >}> >}> }>

>

java версія linux
>

Вихід

Sending Hi Hi Sent Sending Bye Bye Sent>

Результат буде однаковим кожного разу, коли ми запускаємо програму.

символи екранування java

Пояснення

У наведеному вище прикладі ми вирішили синхронізувати об’єкт Sender всередині методу run() класу ThreadedSend. Крім того, ми могли б визначити весь блок send() як синхронізований , дає той самий результат. Тоді нам не потрібно синхронізувати об’єкт Message всередині методу run() у класі 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'); } }>

Нам не завжди потрібно синхронізувати весь метод. Іноді це краще синхронізувати лише частину методу . Синхронізовані блоки Java всередині методів роблять це можливим.

// 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'); } } }>

Приклад синхронізованого методу з використанням анонімного класу

Java




// 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();> >}> }>

>

>

покажчик розіменування c
Вихід

16 17 18 31 32 33>