Rumah  >  Artikel  >  Java  >  Bagaimana untuk melaksanakan kunci diedarkan Java

Bagaimana untuk melaksanakan kunci diedarkan Java

王林
王林ke hadapan
2023-04-25 18:19:071789semak imbas

1. Pengenalan kepada kunci teragih

Mesin tunggal berbilang benang: Di Java, kami biasanya menggunakan kunci tempatan seperti kelas ReetrantLock dan kata kunci yang disegerakkan untuk mengawal berbilang benang dalam proses JVM untuk mengakses perkongsian setempat sumber. Jika berbilang proses JVM berkongsi sumber yang sama, tiada cara untuk mencapai akses eksklusif bersama kepada sumber menggunakan kunci tempatan. Oleh itu, kunci yang diedarkan dilahirkan.

Contohnya: Sebanyak 3 salinan perkhidmatan pesanan sistem digunakan, semuanya menyediakan perkhidmatan kepada dunia luar. Pengguna perlu menyemak inventori sebelum membuat pesanan Untuk mengelakkan penjualan berlebihan, kunci diperlukan untuk mencapai akses segerak kepada operasi semakan inventori. Memandangkan perkhidmatan pesanan terletak dalam proses JVM yang berbeza, kunci tempatan tidak akan berfungsi dengan betul dalam kes ini. Kita perlu menggunakan kunci yang diedarkan, supaya walaupun beberapa utas tidak berada dalam proses JVM yang sama, mereka boleh mendapatkan kunci yang sama, dengan itu mencapai akses eksklusif bersama kepada sumber yang dikongsi. Bagaimana untuk melaksanakan kunci diedarkan Java

Kunci teragih paling asas perlu dipenuhi:

Bagaimana untuk melaksanakan kunci diedarkan Java

Pengecualian bersama: pada bila-bila masa, kunci hanya boleh dipegang oleh satu utas Tahan;

  • Sangat tersedia: Perkhidmatan kunci sangat tersedia. Lebih-lebih lagi, walaupun terdapat masalah dengan logik kod pelanggan untuk melepaskan kunci, kunci itu akhirnya akan dilepaskan dan tidak akan menjejaskan akses utas lain kepada sumber yang dikongsi.

  • Pendaftar semula: Selepas nod memperoleh kunci, ia boleh memperoleh kunci itu semula.

  • 2. Laksanakan kunci teragih berdasarkan Redis

    1 Cara melaksanakan kunci teragih paling mudah berdasarkan Redis
Sama ada kunci tempatan. atau Teras kunci yang diedarkan terletak pada == "pengecualian bersama" ==.

Di Redis, perintah

boleh membantu kita mencapai pengecualian bersama.

Iaitu, SET if Not eXists (sepadan dengan kaedah setIfAbsent dalam Java Jika kunci tidak wujud, nilai kunci akan ditetapkan). Jika kunci sudah wujud, SETNX tidak melakukan apa-apa.

> SETNX lockKey uniqueValueSETNX(integer) 1SETNX> SETNX lockKey uniqueValue

(integer) 0


terus Padamkan kekunci yang sepadan melalui arahan DEL

> DEL lockKey
(integer) 1

Untuk mengelakkan pemadaman kunci lain secara tidak sengaja, kami mengesyorkan di sini Gunakan skrip Lua untuk menilai dengan nilai (nilai unik) yang sepadan dengan kunci.


Skrip Lua dipilih untuk memastikan keatoman operasi buka kunci. Kerana Redis boleh melaksanakan skrip Lua dengan cara atom, dengan itu memastikan keatoman operasi pelepasan kunci.

Ini adalah pelaksanaan kunci teragih Redis yang paling mudah Kaedah pelaksanaannya agak mudah dan prestasinya sangat cekap. Walau bagaimanapun, terdapat beberapa masalah dengan melaksanakan penguncian teragih dengan cara ini. Contohnya, jika aplikasi menghadapi beberapa masalah, seperti logik untuk melepaskan kunci tiba-tiba ditutup, kunci mungkin tidak dilepaskan dan sumber yang dikongsi tidak lagi boleh diakses oleh urutan/proses lain.
// 释放锁时,先比较锁对应的 value 值是否相等,避免锁的误释放
if redis.call("get",KEYS[1]) == ARGV[1] then
    return redis.call("del",KEYS[1])
else
    return 0
end

2. Mengapakah kita perlu menetapkan masa tamat tempoh untuk kunci Bagaimana untuk melaksanakan kunci diedarkan Java

Terutamanya untuk mengelakkan kunci daripada dilepaskan

127.0.0.1:6379> uniqueValue EX 3 NX

OK


lockKey: nama kunci;

  • uniqueValue: rentetan rawak yang mengenal pasti secara unik kunci;

  • NX: SET hanya boleh berjaya apabila nilai kunci yang sepadan dengan lockKey tidak wujud; dalam saat) ) EX 3 menunjukkan bahawa kunci ini mempunyai masa tamat tempoh automatik selama 3 saat. Sepadan dengan EX ialah PX (dalam milisaat), kedua-duanya adalah tetapan masa tamat tempoh.

  • Pastikan anda memastikan bahawa menetapkan nilai dan masa tamat tempoh kunci yang ditentukan ialah operasi atom! ! ! Jika tidak, mungkin masih terdapat masalah bahawa kunci tidak boleh dilepaskan.

    Penyelesaian ini juga mempunyai kelemahan:
  • Jika masa untuk mengendalikan sumber yang dikongsi lebih besar daripada masa tamat tempoh, akan ada masalah tamat tempoh awal kunci , yang akan membawa kepada kunci teragih Kegagalan langsung

Jika tamat masa kunci ditetapkan terlalu lama, ia akan menjejaskan prestasi

  • 3 mencapai pembaharuan kunci yang anggun

    Redisson ialah klien Redis bahasa Java sumber terbuka yang menyediakan banyak ciri luar kotak, termasuk bukan sahaja pelaksanaan berbilang kunci teragih. Selain itu, Redisson juga menyokong berbilang seni bina penggunaan seperti Redis berdiri sendiri, Redis Sentinel dan Redis Cluster.
  • Kunci yang diedarkan dalam Redisson dilengkapi dengan mekanisme pembaharuan automatik Ia sangat mudah digunakan dan prinsipnya agak mudah. ​​Ia menyediakan Watch Dog yang digunakan khas untuk memantau dan memperbaharui kunci sumber yang dikongsi belum menyelesaikan pelaksanaannya, Watch Dog akan terus memanjangkan masa tamat tempoh kunci untuk memastikan bahawa kunci tidak akan dilepaskan kerana tamat masa.

    Bagaimana untuk melaksanakan kunci diedarkan Java

    使用方式举例:

    // 1.获取指定的分布式锁对象
    RLock lock = redisson.getLock("lock");
    // 2.拿锁且不设置锁超时时间,具备 Watch Dog 自动续期机制
    lock.lock();
    // 3.执行业务
    ...
    // 4.释放锁
    lock.unlock();

    只有未指定锁超时时间,才会使用到 Watch Dog 自动续期机制。

    // 手动给锁设置过期时间,不具备 Watch Dog 自动续期机制
    lock.lock(10, TimeUnit.SECONDS);

    总的来说就是使用Redisson,它带有自动的续期机制

    4. 如何实现可重入锁

    所谓可重入锁指的是在一个线程中可以多次获取同一把锁,比如一个线程在执行一个带锁的方法,该方法中又调用了另一个需要相同锁的方法,则该线程可以直接执行调用的方法即可重入 ,而无需重新获得锁。像 Java 中的 synchronized 和 ReentrantLock 都属于可重入锁。

    可重入分布式锁的实现核心思路是线程在获取锁的时候判断是否为自己的锁,如果是的话,就不用再重新获取了。为此,我们可以为每个锁关联一个可重入计数器和一个占有它的线程。当可重入计数器大于 0 时,则锁被占有,需要判断占有该锁的线程和请求获取锁的线程是否为同一个。

Atas ialah kandungan terperinci Bagaimana untuk melaksanakan kunci diedarkan 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