Rumah  >  Artikel  >  Java  >  Cara menggunakan kunci StampedLock dalam pengaturcaraan serentak Java

Cara menggunakan kunci StampedLock dalam pengaturcaraan serentak Java

WBOY
WBOYke hadapan
2023-04-24 08:01:061291semak imbas

StampedLock:

StampedLock ialah kunci baharu yang ditambahkan pada versi JDK8 dalam pakej serentak Kunci ini menyediakan tiga mod kawalan baca dan tulis apabila memanggil siri memperoleh kunci Apabila fungsi dipanggil, pembolehubah panjang akan dikembalikan, yang kami panggil setem ini mewakili status kunci. Siri cuba fungsi yang memperoleh kunci akan mengembalikan nilai setem 0 apabila pemerolehan kunci gagal. Apabila memanggil kaedah melepaskan kunci dan menukar kunci, anda perlu memasukkan nilai setem yang dikembalikan apabila memperoleh kunci.

Tiga kunci mod baca dan tulis yang disediakan oleh StampedLock adalah seperti berikut:

  • Write lock witeLock: ialah row Ia mengunci atau mengunci secara eksklusif Hanya satu utas boleh memperoleh kunci pada satu masa Apabila utas memperoleh kunci, utas lain yang meminta kunci baca dan kunci tulis ini sama dengan kunci tulis ReentrantReadWriteLock (perbezaannya ialah kunci tulis di sini Kunci ialah kunci bukan masuk semula): Kunci hanya boleh diperoleh apabila tiada benang pada masa ini memegang kunci baca atau kunci tulis. Selepas berjaya meminta kunci, pembolehubah setem akan dikembalikan untuk mewakili versi kunci Apabila kunci dilepaskan, kaedah unlockWrite perlu dipanggil dan parameter setem tarikh kunci berlalu. Dan ia menyediakan kaedah tryWriteLock yang tidak menyekat.

  • Baca kunci baca yang pesimis: ialah kunci kongsi Apabila tiada utas memperoleh kunci tulis eksklusif, beberapa utas boleh memperoleh kunci pada masa yang sama. Jika benang sudah memegang kunci tulis, permintaan utas lain untuk memperoleh kunci baca akan disekat, yang serupa dengan kunci baca ReentrantReadWriteLock (perbezaannya ialah kunci baca di sini bukan kunci masuk semula). Pesimisme yang dinyatakan di sini bermaksud bahawa sebelum mengendalikan data secara khusus, ia akan secara pesimis percaya bahawa utas lain mungkin mengubah suai data yang dikendalikannya, jadi ia perlu mengunci data terlebih dahulu. Ini adalah pertimbangan apabila kurang membaca dan menulis lebih banyak. Selepas berjaya meminta kunci, pembolehubah setem akan dikembalikan untuk mewakili versi kunci Apabila kunci dilepaskan, kaedah buka kunciBaca perlu dipanggil dan parameter setem diluluskan. Dan ia menyediakan kaedah tryReadLock yang tidak menyekat.

  • Kunci baca optimis cubaOptimisticRead: Ia adalah relatif kepada kunci pesimis Status kunci tidak ditetapkan melalui CAS sebelum mengendalikan data, hanya operasi bit digunakan. ujian. Jika tiada benang yang memegang kunci tulis pada masa ini, maklumat versi setem bukan sifar akan dikembalikan dengan mudah. Selepas mendapatkan setem, anda perlu memanggil kaedah pengesahan untuk mengesahkan sama ada setem tidak lagi tersedia sebelum mengendalikan data secara khusus, iaitu, sama ada terdapat benang lain yang memegang kunci tulis antara masa apabila tryOptimisticRead mengembalikan setem dan arus masa. Jika ya, sahkan akan Kembali 0 jika tidak, anda boleh menggunakan versi setem kunci untuk mengendalikan data. Memandangkan tryOptimisticRead tidak menggunakan CAS untuk menetapkan status kunci, tidak ada keperluan untuk melepaskan kunci secara eksplisit. Satu ciri kunci ini ialah ia sesuai untuk senario di mana terdapat banyak bacaan dan sedikit tulisan Kerana memperoleh kunci baca hanya menggunakan operasi bit untuk pengesahan dan tidak melibatkan operasi CAS, bagaimanapun, pada tahap masa yang sama, kerana tiada kunci sebenar digunakan, ketekalan data adalah perlu untuk menyalin pembolehubah yang akan dikendalikan ke susunan kaedah, dan apabila mengendalikan data, benang penulisan lain mungkin telah mengubah suai data, dan apa yang kami kendalikan. data dalam timbunan kaedah, yang merupakan petikan, jadi yang paling banyak dikembalikan bukanlah data terkini, tetapi konsistensi masih terjamin.

StampedLock juga menyokong penukaran bersama ketiga-tiga kunci ini dalam keadaan tertentu. Contohnya, long tryConvertToWriteLock(setem panjang) menjangkakan untuk menaik taraf kunci yang ditandakan dengan setem kepada kunci tulis

Fungsi ini akan mengembalikan setem yang sah dalam situasi berikut (iaitu kunci tulis. promosi berjaya) :

  • Kunci semasa sudah berada dalam mod kunci tulis.

  • Kunci sebelumnya berada dalam mod kunci baca dan tiada utas lain dalam mod kunci baca

  • Ia kini dalam mod baca optimistik, dan kunci tulis kini tersedia

Selain itu, kunci baca dan tulis StampedLock ialah kunci bukan masuk semula, jadi selepas memperoleh kunci dan sebelum melepaskan kunci, anda harus bukan operasi panggilan yang akan memperoleh kunci untuk mengelak menyebabkan panggilan Benang disekat. Apabila beberapa utas cuba memperoleh kunci baca dan tulis kunci pada masa yang sama, tiada peraturan tertentu untuk siapa yang memperoleh kunci terlebih dahulu Ia dilakukan sepenuhnya atas dasar usaha terbaik dan adalah rawak. Dan kunci tidak secara langsung melaksanakan antara muka Lock atau ReadWriteLock, tetapi mengekalkan baris gilir sekatan dua hala secara dalaman.

Berikut ialah contoh mengurus mata dua dimensi yang disediakan dalam JDK8 untuk memahami konsep yang diperkenalkan di atas.

package LockSupportTest;

import com.sun.org.apache.bcel.internal.generic.BREAKPOINT;

import java.util.concurrent.locks.StampedLock;

public class Point_Class {
    private double x,y;
    private final StampedLock sl = new StampedLock();
    
    void move(double deltaX, double deltaY) {
        long stamp = sl.writeLock();
        try {
            x += deltaX;
            y += deltaY;
        } finally {
            sl.unlockWrite(stamp);
        }
    }
    
    double distanceFromOrin() {
        long stamp = sl.tryOptimisticRead();
        double currentX = x, currentY = y;
        if (!sl.validate(stamp)) {
            stamp = sl.readLock();
            try {
                currentX = x;
                currentY = y;
            } finally {
                sl.unlockRead(stamp);
            }
        }
        return Math.sqrt(currentX*currentX + currentY*currentY);
    }
    
    void moveIfAtOrigin(double newX, double newY) {
        long stamp = sl.readLock();
        try {
            while (x == 0.0 && y == 0.0) {
                long ws = sl.tryConvertToWriteLock(stamp);
                if (ws != 0L) {
                    stamp = ws;
                    x = newX;
                    y = newY;
                    break;
                } else {
                    sl.unlockRead(stamp);
                    stamp = sl.writeLock();
                }
            }
        } finally {
                    sl.unlock(stamp);
                }
            }
}

Dalam kod di atas, kelas Point mempunyai dua pembolehubah ahli (x, y) yang digunakan untuk mewakili koordinat dua dimensi suatu titik dan tiga kaedah untuk mengendalikan pembolehubah koordinat. Di samping itu, objek StampedLock dibuat seketika untuk memastikan keatoman operasi.

Atas ialah kandungan terperinci Cara menggunakan kunci StampedLock dalam pengaturcaraan serentak Java. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Kenyataan:
Artikel ini dikembalikan pada:yisu.com. Jika ada pelanggaran, sila hubungi admin@php.cn Padam