Rumah  >  Artikel  >  Java  >  Menguasai kunci Java sepenuhnya (analisis grafik dan teks)

Menguasai kunci Java sepenuhnya (analisis grafik dan teks)

WBOY
WBOYke hadapan
2022-06-14 11:47:321907semak imbas

Artikel ini membawa anda pengetahuan yang berkaitan tentang java, yang terutamanya memperkenalkan isu berkaitan kunci java, termasuk kunci eksklusif, kunci pesimis, kunci optimistik, kunci kongsi, dll. , mari kita lihat bersama-sama , saya harap ia akan membantu semua orang.

Menguasai kunci Java sepenuhnya (analisis grafik dan teks)

Pembelajaran yang disyorkan: "tutorial video java"

Kunci optimis dan kunci pesimis

Pesimis Kunci

悲观锁 sepadan dengan orang yang pesimis dalam kehidupan sentiasa berfikir tentang perkara yang pergi ke arah yang salah.

Untuk memberi contoh dalam kehidupan, andaikan hanya ada satu lubang dalam tandas Jika anda mengunci tandas secara pesimis, anda akan mengunci pintu dengan segera, supaya orang lain yang pergi ke tandas hanya boleh menunggu di luar. pintu. Keadaan ini "tersekat".

Kembali dalam dunia kod, kunci pesimis ditambahkan pada data kongsi Setiap kali urutan ingin mengendalikan data ini, ia akan menganggap bahawa urutan lain juga mungkin mengendalikan data ini, jadi ia akan dikunci sebelum setiap satu. operasi, jadi utas lain yang ingin mengendalikan data ini tidak boleh mendapatkan kunci dan hanya boleh disekat.

Menguasai kunci Java sepenuhnya (analisis grafik dan teks)

Dalam bahasa Java, synchronized dan ReentrantLock ialah kunci pesimis biasa, begitu juga beberapa kelas kontena yang menggunakan kata kunci yang disegerakkan, seperti HashTable Aplikasi penguncian pesimis.

Kunci Optimis

乐观锁 Sepadan dengan orang yang optimistik dalam kehidupan sentiasa berfikir tentang perkara yang menuju ke arah yang baik.

Untuk memberi contoh dalam kehidupan, andaikan hanya ada satu lubang di dalam tandas Optimistic Lock berfikir: Tidak ramai orang di hutan belantara ini, dan tiada siapa yang akan merampas lubang saya , kunci je, buang masa, lebih baik jangan kunci. Anda lihat, kunci optimis dilahirkan optimistik!

Kembali dalam dunia kod, penguncian optimistik tidak akan dikunci semasa mengemas kini data, ia akan menentukan sama ada urutan lain akan mengemas kini data dalam tempoh ini.

Menguasai kunci Java sepenuhnya (analisis grafik dan teks)

Penguncian optimis boleh dilaksanakan menggunakan 版本号机制 dan CAS算法. Dalam bahasa Java, kelas atom di bawah pakej java.util.concurrent.atomic dilaksanakan menggunakan penguncian optimistik CAS.

Senario penggunaan dua kunci

Tiada kelebihan atau kekurangan antara kunci pesimis dan kunci optimis, dan mereka mempunyai senario sendiri untuk disesuaikan.

Penguncian optimistik sesuai untuk senario di mana terdapat sedikit penulisan (konflik yang agak kecil kerana tidak perlu mengunci atau melepaskan kunci, overhed penguncian dihapuskan, dengan itu meningkatkan daya pemprosesan).

Jika senario dengan lebih banyak penulisan dan kurang bacaan, iaitu konflik adalah serius dan persaingan antara utas dirangsang, menggunakan kunci optimistik akan menyebabkan utas sentiasa mencuba semula, yang mungkin juga mengurangkan prestasi dalam senario ini , gunakan kunci pesimis Ia lebih sesuai.

Kunci eksklusif dan kunci kongsi

Kunci eksklusif

独占锁 bermakna kunci hanya boleh dipegang oleh satu utas pada satu masa. Jika benang menambah kunci eksklusif pada data, urutan lain tidak lagi boleh menambah sebarang jenis kunci pada data. Urutan yang memperoleh kunci eksklusif boleh membaca dan mengubah suai data.

Menguasai kunci Java sepenuhnya (analisis grafik dan teks)

Kelas pelaksanaan Lock dalam pakej synchronized dan java.util.concurrent(JUC) dalam JDK ialah kunci eksklusif.

Kunci dikongsi

共享锁 bermakna kunci boleh dipegang oleh berbilang benang. Jika urutan menambahkan kunci kongsi pada data, urutan lain hanya boleh menambah kunci kongsi pada data dan tidak boleh menambah kunci eksklusif. Benang yang memperoleh kunci kongsi hanya boleh membaca data dan tidak boleh mengubah suai data.

Menguasai kunci Java sepenuhnya (analisis grafik dan teks)

Dalam JDK, ReentrantReadWriteLock ialah kunci kongsi.

Kunci Mutex dan kunci baca-tulis

Kunci Mutex

互斥锁 ialah pelaksanaan konvensional kunci eksklusif, yang merujuk kepada sumber membenarkan hanya seorang pelawat mengaksesnya pada masa yang sama dan unik dan eksklusif.

Menguasai kunci Java sepenuhnya (analisis grafik dan teks)

Kunci mutex Hanya satu utas boleh memiliki kunci mutex pada satu masa dan utas lain hanya boleh menunggu.

Kunci baca-tulis

读写锁 ialah pelaksanaan khusus kunci kongsi. Kunci baca-tulis mengurus satu set kunci, satu kunci baca sahaja dan satu lagi kunci tulis.

Kunci baca boleh dipegang oleh berbilang utas pada masa yang sama apabila tiada kunci tulis dan kunci tulis adalah eksklusif. Keutamaan kunci tulis adalah lebih tinggi daripada kunci baca Urutan yang memperoleh kunci baca mesti dapat melihat kandungan yang dikemas kini oleh kunci tulis yang dikeluarkan sebelum ini.

Kunci baca-tulis mempunyai tahap konkurensi yang lebih tinggi daripada kunci mutex Hanya terdapat satu utas tulisan pada satu masa, tetapi beberapa utas boleh membaca serentak pada masa yang sama.

Menguasai kunci Java sepenuhnya (analisis grafik dan teks)

mentakrifkan antara muka kunci baca-tulis dalam JDK: ReadWriteLock

public interface ReadWriteLock {
    /**
     * 获取读锁
     */
    Lock readLock();

    /**
     * 获取写锁
     */
    Lock writeLock();
}

ReentrantReadWriteLock melaksanakan antara muka ReadWriteLock, khususnya The pelaksanaan tidak akan dikembangkan di sini, dan analisis kod sumber akan mendalam kemudian.

Kunci adil dan kunci tidak adil

Kunci saksama

公平锁 bermakna berbilang utas memperoleh kunci mengikut susunan ia memohon kunci, di sini Sama seperti beratur untuk membeli tiket, mereka yang datang dahulu membeli, dan mereka yang datang kemudian menunggu dalam barisan di penghujung.

Menguasai kunci Java sepenuhnya (analisis grafik dan teks)

Di java, kunci adil boleh dimulakan melalui pembina

/**
* 创建一个可重入锁,true 表示公平锁,false 表示非公平锁。默认非公平锁
*/
Lock lock = new ReentrantLock(true);

Kunci tidak adil

非公平锁 bermaksud bahawa urutan berbilang benang memperoleh kunci tidak mengikut urutan yang digunakan untuk kunci. Kemungkinan benang yang digunakan kemudian memperoleh kunci sebelum benang yang digunakan terlebih dahulu, ini mungkin menyebabkan keutamaan membalik atau kebuluran Status (benang tidak pernah mendapat kunci).

Menguasai kunci Java sepenuhnya (analisis grafik dan teks)

Kata kunci yang disegerakkan dalam java ialah kunci yang tidak adil, dan ReentrantLock juga merupakan kunci yang tidak adil secara lalai.

/**
* 创建一个可重入锁,true 表示公平锁,false 表示非公平锁。默认非公平锁
*/
Lock lock = new ReentrantLock(false);

Kunci masuk semula

可重入锁 juga dipanggil 递归锁, yang bermaksud benang yang sama memperoleh kunci dalam kaedah luar dan akan memperolehnya secara automatik apabila memasuki kaedah dalam Kunci.

Menguasai kunci Java sepenuhnya (analisis grafik dan teks)

Untuk Java ReentrantLock, namanya boleh memberitahu bahawa ia adalah kunci reentrant. Untuk Disegerakkan, ia juga merupakan kunci masuk semula.

Ketuk papan hitam: Satu faedah kunci masuk semula ialah kebuntuan boleh dielakkan pada tahap tertentu.

Ambil disegerakkan sebagai contoh Lihat kod berikut:

public synchronized void mehtodA() throws Exception{
 // Do some magic tings
 mehtodB();
}

public synchronized void mehtodB() throws Exception{
 // Do some magic tings
}

Dalam kod di atas, methodA memanggil methodB Jika thread memanggil methodA dan telah memperoleh kunci, maka tidak perlu memanggil kaedahB. Kunci diperoleh semula. Ini adalah ciri kunci masuk semula. Jika ia bukan kunci masuk semula, mehtodB mungkin tidak dilaksanakan oleh urutan semasa, yang boleh menyebabkan kebuntuan.

Kunci putaran

自旋锁 bermakna benang tidak digantung secara langsung apabila kunci tidak diperolehi, tetapi melaksanakan gelung sibuk ini adalah apa yang dipanggil putaran.

Menguasai kunci Java sepenuhnya (analisis grafik dan teks)

Tujuan kunci putaran adalah untuk mengurangkan peluang benang digantung, kerana penggantungan benang dan bangun tidur juga merupakan operasi yang memakan sumber.

Jika kunci diduduki oleh benang lain untuk masa yang lama, benang semasa masih akan digantung walaupun selepas berputar, dan gelung sibuk akan menjadi pembaziran sumber sistem, yang sebenarnya akan mengurangkan prestasi keseluruhan. Oleh itu, kunci putaran tidak sesuai untuk situasi konkurensi di mana kunci mengambil masa yang lama.

Di Java, kelas AtomicInteger mempunyai operasi putaran Mari kita lihat kod:

public final int getAndAddInt(Object o, long offset, int delta) {
    int v;
    do {
        v = getIntVolatile(o, offset);
    } while (!compareAndSwapInt(o, offset, v, v + delta));
    return v;
}

Jika operasi CAS gagal, ia akan terus menggelung untuk mendapatkan arus. nilai dan kemudian cuba lagi.

Selain itu, kunci putaran adaptif juga perlu difahami.

Putaran suai telah diperkenalkan dalam JDK1.6 Ini adalah lebih pintar Masa putaran tidak lagi ditentukan oleh masa putaran sebelumnya pada kunci yang sama dan status pemilik kunci . Jika mesin maya berpendapat bahawa putaran ini berkemungkinan besar untuk berjaya lagi, ia akan mengambil lebih banyak masa Jika putaran jarang berjaya, ia mungkin secara langsung meninggalkan proses putaran pada masa hadapan untuk mengelakkan pembaziran sumber pemproses.

Kunci bersegmen

分段锁 ialah reka bentuk kunci, bukan kunci khusus.

Tujuan reka bentuk kunci bersegmen adalah untuk memperhalusi lagi butiran kunci Apabila operasi tidak perlu mengemas kini keseluruhan tatasusunan, hanya satu item dalam tatasusunan boleh dikunci.

Menguasai kunci Java sepenuhnya (analisis grafik dan teks)

Dalam bahasa Java, CurrentHashMap menggunakan kunci segmentasi di lapisan bawah Menggunakan Segmen, ia boleh digunakan secara serentak.

Naik taraf kunci (tiada kunci|kunci berat sebelah|kunci ringan|kunci berat)

JDK1.6 Untuk meningkatkan prestasi dan mengurangkan penggunaan yang disebabkan oleh memperoleh dan melepaskan kunci, JDK1.6 memperkenalkan Terdapat 4 keadaan kunci: 无锁, 偏向锁, 轻量级锁 dan 重量级锁, yang akan meningkat secara beransur-ansur disebabkan persaingan berbilang benang, tetapi tidak boleh diturunkan taraf.

Tiada kunci

无锁Status sebenarnya ialah kunci optimistik yang dinyatakan di atas, yang tidak akan diterangkan di sini.

Kunci bias

Java偏向锁(Biased Locking)是指它会偏向于第一个访问锁的线程,如果在运行过程中,只有一个线程访问加锁的资源,不存在多线程竞争的情况,那么线程是不需要重复获取锁的,这种情况下,就会给线程加一个偏向锁。

偏向锁的实现是通过控制对象Mark Word的标志位来实现的,如果当前是可偏向状态,需要进一步判断对象头存储的线程 ID 是否与当前线程 ID 一致,如果一致直接进入。

轻量级锁

当线程竞争变得比较激烈时,偏向锁就会升级为轻量级锁,轻量级锁认为虽然竞争是存在的,但是理想情况下竞争的程度很低,通过自旋方式等待上一个线程释放锁。

重量级锁

如果线程并发进一步加剧,线程的自旋超过了一定次数,或者一个线程持有锁,一个线程在自旋,又来了第三个线程访问时(反正就是竞争继续加大了),轻量级锁就会膨胀为重量级锁,重量级锁会使除了此时拥有锁的线程以外的线程都阻塞。

升级到重量级锁其实就是互斥锁了,一个线程拿到锁,其余线程都会处于阻塞等待状态。

在 Java 中,synchronized 关键字内部实现原理就是锁升级的过程:无锁 --> 偏向锁 --> 轻量级锁 --> 重量级锁。这一过程在后续讲解 synchronized 关键字的原理时会详细介绍。

锁优化技术(锁粗化、锁消除)

锁粗化

锁粗化就是将多个同步块的数量减少,并将单个同步块的作用范围扩大,本质上就是将多次上锁、解锁的请求合并为一次同步请求。

举个例子,一个循环体中有一个代码同步块,每次循环都会执行加锁解锁操作。

private static final Object LOCK = new Object();

for(int i = 0;i <p>经过<code>锁粗化</code>后就变成下面这个样子了:</p><pre class="brush:php;toolbar:false"> synchronized(LOCK){
     for(int i = 0;i <p><strong>锁消除</strong></p><p><code>锁消除</code>是指虚拟机编译器在运行时检测到了共享数据没有竞争的锁,从而将这些锁进行消除。</p><p>举个例子让大家更好理解。</p><pre class="brush:php;toolbar:false">public String test(String s1, String s2){
    StringBuffer stringBuffer = new StringBuffer();
    stringBuffer.append(s1);
    stringBuffer.append(s2);
    return stringBuffer.toString();
}

上面代码中有一个 test 方法,主要作用是将字符串 s1 和字符串 s2 串联起来。

test 方法中三个变量s1, s2, stringBuffer, 它们都是局部变量,局部变量是在栈上的,栈是线程私有的,所以就算有多个线程访问 test 方法也是线程安全的。

我们都知道 StringBuffer 是线程安全的类,append 方法是同步方法,但是 test 方法本来就是线程安全的,为了提升效率,虚拟机帮我们消除了这些同步锁,这个过程就被称为锁消除

StringBuffer.class

// append 是同步方法
public synchronized StringBuffer append(String str) {
    toStringCache = null;
    super.append(str);
    return this;
}

一张图总结:

前面讲了 Java 语言中各种各种的锁,最后再通过六个问题统一总结一下:

Menguasai kunci Java sepenuhnya (analisis grafik dan teks)

推荐学习:《java视频教程

Atas ialah kandungan terperinci Menguasai kunci Java sepenuhnya (analisis grafik dan teks). Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

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