CodeGym/Kurso sa Java/Modyul 3/Atomic Operations sa Java

Atomic Operations sa Java

Available

Mga kinakailangan para sa paglitaw ng mga pagpapatakbo ng atomic

Tingnan natin ang halimbawang ito para matulungan kang maunawaan kung paano gumagana ang atomic operations:

public class Counter {
    int count;

    public void increment() {
        count++;
    }
}

Kapag mayroon kaming isang thread, gumagana ang lahat, ngunit kung magdaragdag kami ng multithreading, makakakuha kami ng mga maling resulta, at lahat dahil ang pagpapatakbo ng pagtaas ay hindi isang operasyon, ngunit tatlo: isang kahilingan upang makuha ang kasalukuyang halagabilangin, pagkatapos ay dagdagan ito ng 1 at isulat muli sabilangin.

At kapag gusto ng dalawang thread na dagdagan ang isang variable, malamang na mawawalan ka ng data. Iyon ay, ang parehong mga thread ay tumatanggap ng 100, bilang isang resulta, pareho ang magsusulat ng 101 sa halip na ang inaasahang halaga ng 102.

At paano ito lutasin? Kailangan mong gumamit ng mga kandado. Nakakatulong ang naka-synchronize na keyword na malutas ang problemang ito, ang paggamit nito ay nagbibigay sa iyo ng garantiya na maa-access ng isang thread ang pamamaraan sa isang pagkakataon.

public class SynchronizedCounterWithLock {
    private volatile int count;

    public synchronized void increment() {
        count++;
    }
}

Dagdag pa, kailangan mong idagdag ang pabagu-bagong keyword , na nagsisiguro ng tamang visibility ng mga sanggunian sa mga thread. Sinuri namin ang kanyang trabaho sa itaas.

Ngunit mayroon pa ring mga downsides. Ang pinakamalaki ay ang performance, sa puntong iyon kapag maraming mga thread ang sumusubok na makakuha ng lock at ang isa ay nakakuha ng pagkakataong magsulat, ang iba pang mga thread ay maaaring ma-block o masususpindi hanggang sa mailabas ang thread.

Ang lahat ng mga prosesong ito, pagharang, paglipat sa ibang katayuan ay napakamahal para sa pagganap ng system.

Mga operasyon ng atom

Gumagamit ang algorithm ng mababang antas ng mga tagubilin sa makina tulad ng compare-and-swap (CAS, compare-and-swap, na nagsisiguro sa integridad ng data at mayroon nang malaking halaga ng pananaliksik sa mga ito).

Ang isang karaniwang operasyon ng CAS ay gumagana sa tatlong operand:

  • Memory space para sa trabaho (M)
  • Umiiral na inaasahang halaga (A) ng isang variable
  • Bagong value (B) na itatakda

Atomically ina-update ng CAS ang M hanggang B, ngunit kung ang halaga ng M ay kapareho ng A, kung hindi, walang gagawing aksyon.

Sa una at pangalawang kaso, ibabalik ang halaga ng M. Nagbibigay-daan ito sa iyong pagsamahin ang tatlong hakbang, ibig sabihin, pagkuha ng halaga, paghahambing ng halaga, at pag-update nito. At lahat ng ito ay nagiging isang operasyon sa antas ng makina.

Sa sandaling ma-access ng isang multi-threaded na application ang isang variable at subukang i-update ito at inilapat ang CAS, pagkatapos ay makukuha ito ng isa sa mga thread at magagawang i-update ito. Ngunit hindi tulad ng mga lock, ang ibang mga thread ay makakakuha lamang ng mga error tungkol sa hindi pag-update ng halaga. Pagkatapos ay magpapatuloy sila sa karagdagang trabaho, at ang paglipat ay ganap na hindi kasama sa ganitong uri ng trabaho.

Sa kasong ito, ang lohika ay nagiging mas mahirap dahil sa katotohanan na kailangan nating pangasiwaan ang sitwasyon kung kailan hindi matagumpay na gumana ang operasyon ng CAS. Imodelo na lang natin ang code para hindi ito umusad hanggang sa magtagumpay ang operasyon.

Panimula sa Mga Uri ng Atomic

Nakarating ka na ba sa isang sitwasyon kung saan kailangan mong mag-set up ng synchronization para sa pinakasimpleng variable ng uri int ?

Ang unang paraan na natalakay na natin ay ang paggamit ng volatile + synchronized . Ngunit mayroon ding mga espesyal na klase ng Atomic*.

Kung gumagamit kami ng CAS, mas mabilis na gagana ang mga operasyon kumpara sa unang paraan. At bilang karagdagan, mayroon kaming mga espesyal at napaka-maginhawang pamamaraan para sa pagdaragdag ng halaga at mga pagpapatakbo ng pagtaas at pagbaba.

Ang AtomicBoolean , AtomicInteger , AtomicLong , AtomicIntegerArray , AtomicLongArray ay mga klase kung saan ang mga operasyon ay atomic. Sa ibaba ay susuriin natin ang gawain sa kanila.

AtomicInteger

Ang klase ng AtomicInteger ay nagbibigay ng mga operasyon sa isang int value na maaaring basahin at isulat nang atomically, bilang karagdagan sa pagbibigay ng mga pinahabang atomic na operasyon.

Mayroon itong makakuha at nagtakda ng mga pamamaraan na gumagana tulad ng pagbabasa at pagsulat ng mga variable.

Iyon ay, "nangyayari-bago" sa anumang kasunod na pagtanggap ng parehong variable na napag-usapan natin kanina. Ang paraan ng atomic compareAndSet ay mayroon ding mga tampok na ito sa pagkakapare-pareho ng memorya.

Ang lahat ng mga operasyon na nagbabalik ng bagong halaga ay ginaganap nang atomically:

int addAndGet (int delta) Nagdaragdag ng isang partikular na halaga sa kasalukuyang halaga.
boolean compareAndSet(expected int, update int) Itinatakda ang halaga sa ibinigay na na-update na halaga kung ang kasalukuyang halaga ay tumutugma sa inaasahang halaga.
int decrementAndGet() Binabawasan ng isa ang kasalukuyang halaga.
int getAndAdd(int delta) Idinaragdag ang ibinigay na halaga sa kasalukuyang halaga.
int getAndDecrement() Binabawasan ng isa ang kasalukuyang halaga.
int getAndIncrement() Pinapataas ng isa ang kasalukuyang halaga.
int getAndSet(int newValue) Itinatakda ang ibinigay na halaga at ibinabalik ang lumang halaga.
int incrementAndGet() Pinapataas ng isa ang kasalukuyang halaga.
lazySet(int newValue) Sa wakas ay itinakda sa ibinigay na halaga.
boolean weakCompareAndSet(inaasahan, i-update int) Itinatakda ang halaga sa ibinigay na na-update na halaga kung ang kasalukuyang halaga ay tumutugma sa inaasahang halaga.

Halimbawa:

ExecutorService executor = Executors.newFixedThreadPool(5);
IntStream.range(0, 50).forEach(i -> executor.submit(atomicInteger::incrementAndGet));
executor.shutdown();
executor.awaitTermination(Long.MAX_VALUE, TimeUnit.HOURS);

System.out.println(atomicInteger.get()); // prints 50
1
Gawain
Modyul 3,  antasaralin
Naka-lock
Earn a Million!
task4201
1
Gawain
Modyul 3,  antasaralin
Naka-lock
Early Bird Gets the Worm
task4202
Mga komento
  • Sikat
  • Bago
  • Luma
Dapat kang naka-sign in upang mag-iwan ng komento
Wala pang komento ang page na ito