logo

Jawa Atomowa

na Jawie, zmienne atomowe I operacje używane współbieżnie. The wielowątkowość środowisko prowadzi do problemu, gdy konkurencja jest ujednolicony. Wspólna jednostka, taka jak obiekty i zmienne, może zostać zmieniona podczas wykonywania programu. Mogą zatem prowadzić do niespójności programu. Dlatego ważne jest, aby dbać o współdzielony obiekt podczas jednoczesnego uzyskiwania dostępu. W takich przypadkach zmienna atomowa może być rozwiązaniem tego problemu. W tej części omówimy klasy atomowe, zmienne atomowe, operacje atomowe , wraz z przykładami.

interfejs vs klasa abstrakcyjna

Zanim przejdziesz dalej w tej sekcji, upewnij się, że jesteś tego świadomy nitka , synchronizacja , I zamek w Jawie.

Klasy atomowe Java

Jawa zapewnia java.util.concurrent.atomic pakiet, w którym zdefiniowano klasy atomowe. Klasy atomowe zapewniają a bez zamka I bezpieczny dla wątków środowisko lub programowanie na pojedynczej zmiennej. Obsługuje również operacje atomowe. Wszystkie klasy atomowe mają metody get() i set(), które działają na zmiennej lotnej. Metoda działa tak samo jak odczyt i zapis zmiennych niestabilnych.

Pakiet udostępnia następujące klasy atomowe:

Klasa Opis
AtomowyBoolean Służy do atomowej aktualizacji wartości logicznej.
Liczba całkowita atomowa Służy do atomowej aktualizacji wartości całkowitej.
Atomowa tablica całkowita Tablica typu int, w której elementy mogą być aktualizowane atomowo.
AtomicIntegerFieldUpdater Narzędzie oparte na refleksjach, które umożliwia atomowe aktualizacje wyznaczonych pól lotnych int wyznaczonych klas.
Atomowy długi Służy do atomowej aktualizacji długich wartości.
Atomowa długa tablica Długa tablica, w której elementy mogą być aktualizowane atomowo.
Aktualizator AtomicLongField Narzędzie oparte na refleksjach, które umożliwia atomowe aktualizacje wyznaczonych lotnych długich pól wyznaczonych klas.
AtomicMarkableReference AtomicMarkableReference przechowuje odniesienie do obiektu wraz z bitem znaku, który można aktualizować atomowo.
Odniesienie atomowe Odniesienie do obiektu, które może być aktualizowane niepodzielnie.
Atomowa tablica referencyjna Tablica odniesień do obiektów, w których elementy mogą być aktualizowane niepodzielnie.
AtomicReferenceFieldUpdater Narzędzie oparte na refleksjach, które umożliwia atomowe aktualizacje wyznaczonych niestabilnych pól referencyjnych wyznaczonych klas.
Odniesienie AtomicStamped AtomicStampedReference przechowuje odniesienie do obiektu wraz ze „znaczkiem” w postaci liczby całkowitej, który można aktualizować atomowo.
Podwójny akumulator Jedna lub więcej zmiennych, które łącznie utrzymują bieżącą wartość podwójną, aktualizowaną przy użyciu dostarczonej funkcji.
Podwójny dodatek Jedna lub więcej zmiennych, które razem utrzymują początkowo zerową sumę podwójną.
Długi akumulator Jedna lub więcej zmiennych, które razem utrzymują długotrwałą wartość, aktualizowaną przy użyciu dostarczonej funkcji.
Długi dodatek Jedna lub więcej zmiennych, które razem utrzymują początkowo zerową sumę.

Obiekty tych klas reprezentują zmienną atomową int, długi, wartość logiczna i obiekt odniesienie odpowiednio. Klasy atomowe mają kilka wspólnych metod, które są następujące:

Metody Opis
ustawić() Służy do ustawienia wartości.
Dostawać() Służy do uzyskania bieżącej wartości.
leniwyZestaw() Ostatecznie ustawia podaną wartość.
porównajAndSet Niepodzielnie ustawia wartość na podaną zaktualizowaną wartość, jeśli bieżąca wartość == wartość oczekiwana.

Operacje atomowe

Operacje, które zawsze są wykonywane razem, nazywane są operacjami operacje atomowe Lub akcja atomowa . Wszystkie operacje atomowe albo są skutecznie wykonywane, albo nie zdarzają się wcale. Trzy Kluczowe pojęcia związane z działaniami atomowymi w Javie są następujące:

1. Atomowość dotyczy działań i zbiorów działań niewidzialny Rozważmy na przykład następujący fragment kodu:

 class NoAtomicOps { long counter=0; void increment() { for(;;) { count++; } } void decrement() { for(;;) { count--; } } //other statement } 

W powyższym kodzie zachowanie jednoczesnego uruchamiania inkrementacji() i dekrementacji() jest następujące nieokreślony I nieprzewidywalne .

2. Widoczność określa, kiedy może nastąpić efekt jednego wątku widziany przez innego. Rozważmy na przykład następujący fragment kodu:

 class InfiniteLoop { boolean done= false; void work() { //thread T2 read while(!done) { //do work } } void stopWork() { //thread T1 write done=true; } //statements } 

W powyższym kodzie możliwe jest, że wątek T2 nigdy się nie zatrzyma nawet po ustawieniu przez wątek T1 wartości true. Nie oznacza to również braku synchronizacji między wątkami.

3. Porządek określa, kiedy działania w jednym wątku występują w niewłaściwej kolejności w odniesieniu do innego wątku.

 class Order { boolean a=false; boolean b=false; void demo1() //thread T1 { a=true; b=true; } boolean demo2() //thread T2 { boolean r1=b; //sees true boolean r2=a; //sees false boolean r3=a; //sees true //returns true return (r1 && !r2) && r3; } } 

Kolejność pól aib w wątku T2 może różnić się od kolejności, w jakiej zostały ustawione w wątku T1.

long do int Java

Rozumiemy to na przykładzie.

 public class AtomicExample { int count; public void incrementCount() { count=1; } 

W powyższym fragmencie kodu zadeklarowaliśmy zmienną typu int liczyć a wewnątrz metody inkrementCount() przypisano jej wartość 1. W takim przypadku albo wszystko wydarzy się razem, albo nie wydarzy się wcale. Dlatego reprezentuje operacja atomowa a operacja jest znana jako atomowość .

Rozważmy inny fragment kodu.

 public class AtomicExample { int count; public void incrementCount() { count=count+1; } 

Wydaje się, że jest to również operacja atomowa, ale tak nie jest. Jest to operacja liniowa składająca się z trzech operacji, tj. odczytu, modyfikacji i zapisu. Dlatego może zostać wykonany częściowo. Ale jeśli używamy powyższego kodu w środowisku wielowątkowym, stwarza to problem.

Załóżmy, że wywołaliśmy powyższy kod w środowisku jednowątkowym, zaktualizowana wartość count wyniesie 2. Jeśli wywołamy powyższą metodę przez dwa oddzielne wątki, oba uzyskują dostęp do zmiennej w tym samym czasie, a także aktualizują wartość liczyć jednocześnie. Aby uniknąć tej sytuacji, stosujemy operację atomową.

algorytm „bankiera”

Java obsługuje kilka typów działań atomowych, są następujące:

  • Lotny zmienne
  • Operacje atomowe niskiego poziomu (niebezpieczne)
  • Klasy atomowe

Zobaczmy, jak możemy stworzyć operację atomową.

Zmienna atomowa

Zmienna atomowa pozwala nam wykonać operację atomową na zmiennej. Zmienne atomowe minimalizują synchronizację i pomagają uniknąć błędów spójności pamięci. Dlatego zapewnia synchronizację.

Pakiet atomowy udostępnia pięć następujących zmiennych atomowych:

  • Liczba całkowita atomowa
  • Atomowy długi
  • AtomowyBoolean
  • Atomowa tablica całkowita
  • Atomowa długa tablica

Potrzeba zmiennej atomowej

Rozważmy następujący kod.

Wiek Vicky Kaushal

Licznik.java

 class Counter extends Thread { // Counter Variable int count = 0; //the method starts the execution of a thread public void run() { int max = 1; //increments the counter variable up to specified max time for (int i = 0; i <max; i++) { count++; } public class counter static void main(string args[]) throws interruptedexception creating an instance of the c="new" counter(); four threads thread t1="new" thread(c, 'first'); t2="new" 'second'); t3="new" 'third'); t4="new" 'fourth'); by calling start() method, we have started t1.start(); t2.start(); t3.start(); t4.start(); main will wait for all until execution do not complete t1.join(); t2.join(); t3.join(); t4.join(); prints final value count variable system.out.println(c.count); < pre> <p> <strong>Output:</strong> </p> <pre> 4 </pre> <p>The above program gives the expected output if it is executed in a single-threaded environment. A multi-threaded environment may lead to unexpected output. The reason behind it that when two or more threads try to update the value at the same time then it may not update properly.</p> <p>Java offers <strong>two</strong> solutions to overcome this problem:</p> <ul> <li>By using lock and synchronization</li> <li>By using atomic variable</li> </ul> <p>Let&apos;s create a Java program and use an atomic variable to overcome the problem.</p> <h3>By using Atomic Variable</h3> <p> <strong>AtomicExample.java</strong> </p> <pre> class Counter extends Thread { // Counter Variable int count = 0; //the method starts the execution of a thread public void run() { int max = 1; //increments the counter variable up to specified max time for (int i = 0; i <max; i++) { count++; } public class counter static void main(string args[]) throws interruptedexception creating an instance of the c="new" counter(); four threads thread t1="new" thread(c, 'first'); t2="new" 'second'); t3="new" 'third'); t4="new" 'fourth'); by calling start() method, we have started t1.start(); t2.start(); t3.start(); t4.start(); main will wait for all until execution do not complete t1.join(); t2.join(); t3.join(); t4.join(); prints final value count variable system.out.println(c.count); < pre> <p> <strong>Output:</strong> </p> <pre> 4 </pre> <h2>Synchronized Vs. Atomic Vs. Volatile</h2> <table class="table"> <tr> <th>Synchronized</th> <th>Atomic</th> <th>Volatile</th> </tr> <tr> <td>It applies to methods only.</td> <td>It applies to variables only.</td> <td>It also applies to variables only.</td> </tr> <tr> <td>It ensures visibility along with atomicity.</td> <td>It also ensures visibility along with atomicity.</td> <td>It ensures visibility, not atomicity.</td> </tr> <tr> <td>We can&apos;t achieve the same.</td> <td>We can&apos;t achieve the same.</td> <td>It stores in RAM, so accessing volatile variables is fast. But it does not provide thread-safety and synchronization.</td> </tr> <tr> <td>It can be implemented as a synchronized block or a synchronized method.</td> <td>We can&apos;t achieve the same.</td> <td>We can&apos;t achieve the same.</td> </tr> <tr> <td>It can lock the same class object or a different class object.</td> <td>We can&apos;t achieve the same.</td> <td>We can&apos;t achieve the same.</td> </tr> </table> <hr></max;></pre></max;>

Powyższy program daje oczekiwany wynik, jeśli jest wykonywany w środowisku jednowątkowym. Środowisko wielowątkowe może prowadzić do nieoczekiwanych wyników. Powodem jest to, że gdy dwa lub więcej wątków próbuje zaktualizować wartość w tym samym czasie, może ona nie zostać poprawnie zaktualizowana.

oferty Java dwa rozwiązania pozwalające przezwyciężyć ten problem:

  • Używając blokady i synchronizacji
  • Używając zmiennej atomowej

Stwórzmy program w języku Java i użyjmy zmiennej atomowej, aby rozwiązać problem.

Używając zmiennej atomowej

AtomicExample.java

 class Counter extends Thread { // Counter Variable int count = 0; //the method starts the execution of a thread public void run() { int max = 1; //increments the counter variable up to specified max time for (int i = 0; i <max; i++) { count++; } public class counter static void main(string args[]) throws interruptedexception creating an instance of the c="new" counter(); four threads thread t1="new" thread(c, \'first\'); t2="new" \'second\'); t3="new" \'third\'); t4="new" \'fourth\'); by calling start() method, we have started t1.start(); t2.start(); t3.start(); t4.start(); main will wait for all until execution do not complete t1.join(); t2.join(); t3.join(); t4.join(); prints final value count variable system.out.println(c.count); < pre> <p> <strong>Output:</strong> </p> <pre> 4 </pre> <h2>Synchronized Vs. Atomic Vs. Volatile</h2> <table class="table"> <tr> <th>Synchronized</th> <th>Atomic</th> <th>Volatile</th> </tr> <tr> <td>It applies to methods only.</td> <td>It applies to variables only.</td> <td>It also applies to variables only.</td> </tr> <tr> <td>It ensures visibility along with atomicity.</td> <td>It also ensures visibility along with atomicity.</td> <td>It ensures visibility, not atomicity.</td> </tr> <tr> <td>We can&apos;t achieve the same.</td> <td>We can&apos;t achieve the same.</td> <td>It stores in RAM, so accessing volatile variables is fast. But it does not provide thread-safety and synchronization.</td> </tr> <tr> <td>It can be implemented as a synchronized block or a synchronized method.</td> <td>We can&apos;t achieve the same.</td> <td>We can&apos;t achieve the same.</td> </tr> <tr> <td>It can lock the same class object or a different class object.</td> <td>We can&apos;t achieve the same.</td> <td>We can&apos;t achieve the same.</td> </tr> </table> <hr></max;>

Zsynchronizowane vs. Atomowa kontra. Lotny

Zsynchronizowane Atomowy Lotny
Dotyczy tylko metod. Dotyczy tylko zmiennych. Dotyczy to również tylko zmiennych.
Zapewnia widoczność i atomowość. Zapewnia także widoczność i atomowość. Zapewnia widoczność, a nie atomowość.
Nie możemy osiągnąć tego samego. Nie możemy osiągnąć tego samego. Przechowuje się w pamięci RAM, więc dostęp do zmiennych zmiennych jest szybki. Nie zapewnia jednak bezpieczeństwa wątków i synchronizacji.
Można go zaimplementować jako blok zsynchronizowany lub metodę zsynchronizowaną. Nie możemy osiągnąć tego samego. Nie możemy osiągnąć tego samego.
Może zablokować ten sam obiekt klasy lub inny obiekt klasy. Nie możemy osiągnąć tego samego. Nie możemy osiągnąć tego samego.