logo

Synchronizacja w Javie

Synchronizacja w Javie to możliwość kontrolowania dostępu wielu wątków do dowolnego współdzielonego zasobu.

Synchronizacja Java jest lepszą opcją, gdy chcemy zezwolić tylko jednemu wątkowi na dostęp do współdzielonego zasobu.

Dlaczego warto korzystać z synchronizacji?

Synchronizacja jest używana głównie do

  1. Aby zapobiec zakłóceniom gwintu.
  2. Aby zapobiec problemom ze spójnością.

Rodzaje synchronizacji

Istnieją dwa rodzaje synchronizacji

  1. Synchronizacja procesów
  2. Synchronizacja wątków

Tutaj omówimy tylko synchronizację wątków.

Synchronizacja wątków

Istnieją dwa typy synchronizacji wątków, wzajemnej wyłączności i komunikacji między wątkami.

  1. Wzajemna wyłączność
    1. Metoda zsynchronizowana.
    2. Zsynchronizowany blok.
    3. Synchronizacja statyczna.
  2. 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. Można to osiągnąć na trzy sposoby:

  1. Za pomocą metody zsynchronizowanej
  2. Za pomocą bloku synchronicznego
  3. Za pomocą synchronizacji statycznej

Koncepcja blokady w Javie

Synchronizacja opiera się na wewnętrznym obiekcie zwanym blokadą lub monitorem. Z każdym obiektem jest powiązana blokada. Zgodnie z konwencją wątek wymagający stałego dostępu do pól obiektu musi uzyskać blokadę obiektu przed uzyskaniem do nich dostępu, a następnie zwolnić blokadę, gdy skończy z nimi.

Od wersji Java 5 pakiet java.util.concurrent.locks zawiera kilka implementacji blokad.

Zrozumienie problemu bez synchronizacji

W tym przykładzie nie ma synchronizacji, więc dane wyjściowe są niespójne. Zobaczmy przykład:

TestSynchronizacja1.java

 class Table{ void printTable(int n){//method not synchronized for(int i=1;i<=5;i++){ system.out.println(n*i); try{ thread.sleep(400); }catch(exception e){system.out.println(e);} } class mythread1 extends thread{ table t; mythread1(table t){ this.t="t;" public void run(){ t.printtable(5); mythread2 mythread2(table t.printtable(100); testsynchronization1{ static main(string args[]){ obj="new" table(); only one object t1="new" mythread1(obj); t2="new" mythread2(obj); t1.start(); t2.start(); < pre> <p> <strong>Output:</strong> </p> <pre> 5 100 10 200 15 300 20 400 25 500 </pre> <h3>Java Synchronized Method</h3> <p>If you declare any method as synchronized, it is known as synchronized method.</p> <p>Synchronized method is used to lock an object for any shared resource.</p> <p>When a thread invokes a synchronized method, it automatically acquires the lock for that object and releases it when the thread completes its task.</p> <p> <strong>TestSynchronization2.java</strong> </p> <pre> //example of java synchronized method class Table{ synchronized void printTable(int n){//synchronized method for(int i=1;i<=5;i++){ system.out.println(n*i); try{ thread.sleep(400); }catch(exception e){system.out.println(e);} } class mythread1 extends thread{ table t; mythread1(table t){ this.t="t;" public void run(){ t.printtable(5); mythread2 mythread2(table t.printtable(100); testsynchronization2{ static main(string args[]){ obj="new" table(); only one object t1="new" mythread1(obj); t2="new" mythread2(obj); t1.start(); t2.start(); < pre> <p> <strong>Output:</strong> </p> <pre> 5 10 15 20 25 100 200 300 400 500 </pre> <h3>Example of synchronized method by using annonymous class</h3> <p>In this program, we have created the two threads by using the anonymous class, so less coding is required.</p> <p> <strong>TestSynchronization3.java</strong> </p> <pre> //Program of synchronized method by using annonymous class class Table{ synchronized void printTable(int n){//synchronized method for(int i=1;i<=5;i++){ system.out.println(n*i); try{ thread.sleep(400); }catch(exception e){system.out.println(e);} } public class testsynchronization3{ static void main(string args[]){ final table obj="new" table(); only one object thread t1="new" thread(){ run(){ obj.printtable(5); }; t2="new" obj.printtable(100); t1.start(); t2.start(); < pre> <p> <strong>Output:</strong> </p> <pre> 5 10 15 20 25 100 200 300 400 500 </pre> <hr></=5;i++){></pre></=5;i++){></pre></=5;i++){>

Metoda synchronizacji Java

Jeśli zadeklarujesz dowolną metodę jako zsynchronizowaną, jest ona nazywana metodą zsynchronizowaną.

Metoda synchronizowana służy do blokowania obiektu dla dowolnego udostępnionego zasobu.

Gdy wątek wywołuje metodę zsynchronizowaną, automatycznie uzyskuje blokadę tego obiektu i zwalnia ją, gdy wątek zakończy swoje zadanie.

TestSynchronization2.java

 //example of java synchronized method class Table{ synchronized void printTable(int n){//synchronized method for(int i=1;i<=5;i++){ system.out.println(n*i); try{ thread.sleep(400); }catch(exception e){system.out.println(e);} } class mythread1 extends thread{ table t; mythread1(table t){ this.t="t;" public void run(){ t.printtable(5); mythread2 mythread2(table t.printtable(100); testsynchronization2{ static main(string args[]){ obj="new" table(); only one object t1="new" mythread1(obj); t2="new" mythread2(obj); t1.start(); t2.start(); < pre> <p> <strong>Output:</strong> </p> <pre> 5 10 15 20 25 100 200 300 400 500 </pre> <h3>Example of synchronized method by using annonymous class</h3> <p>In this program, we have created the two threads by using the anonymous class, so less coding is required.</p> <p> <strong>TestSynchronization3.java</strong> </p> <pre> //Program of synchronized method by using annonymous class class Table{ synchronized void printTable(int n){//synchronized method for(int i=1;i<=5;i++){ system.out.println(n*i); try{ thread.sleep(400); }catch(exception e){system.out.println(e);} } public class testsynchronization3{ static void main(string args[]){ final table obj="new" table(); only one object thread t1="new" thread(){ run(){ obj.printtable(5); }; t2="new" obj.printtable(100); t1.start(); t2.start(); < pre> <p> <strong>Output:</strong> </p> <pre> 5 10 15 20 25 100 200 300 400 500 </pre> <hr></=5;i++){></pre></=5;i++){>

Przykład metody synchronized przy użyciu klasy anonimowej

W tym programie utworzyliśmy dwa wątki przy użyciu klasy anonimowej, więc potrzeba mniej kodowania.

TestSynchronizacja3.java

 //Program of synchronized method by using annonymous class class Table{ synchronized void printTable(int n){//synchronized method for(int i=1;i<=5;i++){ system.out.println(n*i); try{ thread.sleep(400); }catch(exception e){system.out.println(e);} } public class testsynchronization3{ static void main(string args[]){ final table obj="new" table(); only one object thread t1="new" thread(){ run(){ obj.printtable(5); }; t2="new" obj.printtable(100); t1.start(); t2.start(); < pre> <p> <strong>Output:</strong> </p> <pre> 5 10 15 20 25 100 200 300 400 500 </pre> <hr></=5;i++){>