CodeGym/Java Course/Modul 3/Operasi Atom di Jawa

Operasi Atom di Jawa

Level 19, Pelajaran 1
Tersedia

Prasyarat munculnya operasi atom

Mari kita lihat contoh ini untuk membantu Anda memahami cara kerja operasi atom:

public class Counter {
    int count;

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

Ketika kami memiliki satu utas, semuanya berfungsi dengan baik, tetapi jika kami menambahkan multithreading, kami mendapatkan hasil yang salah, dan semua karena operasi kenaikan bukan satu operasi, tetapi tiga: permintaan untuk mendapatkan nilai saat inimenghitung, lalu tingkatkan dengan 1 dan tulis lagi kemenghitung.

Dan ketika dua utas ingin menambah variabel, kemungkinan besar Anda akan kehilangan data. Artinya, kedua utas menerima 100, akibatnya, keduanya akan menulis 101, bukan nilai yang diharapkan 102.

Dan bagaimana cara mengatasinya? Anda perlu menggunakan kunci. Kata kunci yang disinkronkan membantu menyelesaikan masalah ini, menggunakannya memberi Anda jaminan bahwa satu utas akan mengakses metode pada satu waktu.

public class SynchronizedCounterWithLock {
    private volatile int count;

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

Plus, Anda perlu menambahkan kata kunci yang mudah menguap , yang memastikan visibilitas referensi yang benar di antara utas. Kami telah meninjau karyanya di atas.

Tapi tetap saja ada kerugiannya. Yang terbesar adalah kinerja, pada saat banyak utas mencoba mendapatkan kunci dan satu mendapat kesempatan menulis, utas lainnya akan diblokir atau ditangguhkan hingga utas dilepaskan.

Semua proses ini, memblokir, beralih ke status lain sangat mahal untuk kinerja sistem.

Operasi atom

Algoritme menggunakan instruksi mesin tingkat rendah seperti bandingkan-dan-tukar (CAS, bandingkan-dan-tukar, yang memastikan integritas data dan sudah ada banyak penelitian tentangnya).

Operasi CAS tipikal beroperasi pada tiga operan:

  • Ruang memori untuk bekerja (M)
  • Nilai harapan (A) yang ada dari suatu variabel
  • Nilai baru (B) yang akan ditetapkan

CAS secara atom memperbarui M ke B, tetapi hanya jika nilai M sama dengan A, jika tidak, tidak ada tindakan yang diambil.

Dalam kasus pertama dan kedua, nilai M akan dikembalikan.Ini memungkinkan Anda menggabungkan tiga langkah, yaitu mendapatkan nilai, membandingkan nilai, dan memperbaruinya. Dan itu semua berubah menjadi satu operasi di tingkat mesin.

Saat aplikasi multi-utas mengakses variabel dan mencoba memperbaruinya dan CAS diterapkan, maka salah satu utas akan mendapatkannya dan dapat memperbaruinya. Tapi tidak seperti kunci, utas lain hanya akan mendapatkan kesalahan karena tidak dapat memperbarui nilainya. Kemudian mereka akan beralih ke pekerjaan selanjutnya, dan peralihan sama sekali tidak termasuk dalam jenis pekerjaan ini.

Dalam hal ini, logika menjadi lebih sulit karena kita harus menangani situasi ketika operasi CAS tidak berhasil. Kami hanya akan memodelkan kode sehingga tidak bergerak sampai operasi berhasil.

Pengantar Jenis Atom

Pernahkah Anda menemukan situasi di mana Anda perlu mengatur sinkronisasi untuk variabel tipe paling sederhana int ?

Cara pertama yang telah kita bahas adalah menggunakan volatile + synchronized . Tapi ada juga kelas Atomic* khusus.

Jika kita menggunakan CAS, maka operasi bekerja lebih cepat dibandingkan dengan cara pertama. Selain itu, kami memiliki metode khusus dan sangat nyaman untuk menambahkan nilai dan operasi kenaikan dan penurunan.

AtomicBoolean , AtomicInteger , AtomicLong , AtomicIntegerArray , AtomicLongArray adalah kelas yang operasinya bersifat atomik. Di bawah ini kami akan menganalisis pekerjaan dengan mereka.

AtomicInteger

Kelas AtomicInteger menyediakan operasi pada nilai int yang dapat dibaca dan ditulis secara atomik, selain menyediakan operasi atomik yang diperluas.

Ini memiliki metode get and set yang berfungsi seperti membaca dan menulis variabel.

Yaitu, "terjadi-sebelumnya" dengan penerimaan selanjutnya dari variabel yang sama yang kita bicarakan sebelumnya. Metode atomik compareAndSet juga memiliki fitur konsistensi memori ini.

Semua operasi yang mengembalikan nilai baru dilakukan secara atomik:

int addAndGet (int delta) Menambahkan nilai tertentu ke nilai saat ini.
boolean bandingkanDanSet(diharapkan int, perbarui int) Tetapkan nilai ke nilai yang diperbarui jika nilai saat ini cocok dengan nilai yang diharapkan.
int penguranganDanDapatkan() Mengurangi nilai saat ini satu per satu.
int getAndAdd(int delta) Menambahkan nilai yang diberikan ke nilai saat ini.
int getAndDecrement() Mengurangi nilai saat ini satu per satu.
int getAndIncrement() Meningkatkan nilai saat ini satu per satu.
int getAndSet(int NilaiBaru) Menetapkan nilai yang diberikan dan mengembalikan nilai lama.
int kenaikanDanDapatkan() Meningkatkan nilai saat ini satu per satu.
lazySet(int NilaiBaru) Terakhir atur ke nilai yang diberikan.
boolean weakCompareAndSet(diharapkan, perbarui int) Tetapkan nilai ke nilai yang diperbarui jika nilai saat ini cocok dengan nilai yang diharapkan.

Contoh:

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
Tugas
Modul 3,  level 19pelajaran 1
Terkunci
Earn a Million!
task4201
1
Tugas
Modul 3,  level 19pelajaran 1
Terkunci
Early Bird Gets the Worm
task4202
Komentar
  • Populer
  • Baru
  • Lama
Anda harus login untuk memberikan komentar
Halaman ini belum memiliki komentar