Menguasai kunci Java sepenuhnya (analisis grafik dan teks)
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.
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.
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.
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.
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.
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.
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.
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.
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).
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.
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.
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.
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 语言中各种各种的锁,最后再通过六个问题统一总结一下:
推荐学习:《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!

Alat AI Hot

Undresser.AI Undress
Apl berkuasa AI untuk mencipta foto bogel yang realistik

AI Clothes Remover
Alat AI dalam talian untuk mengeluarkan pakaian daripada foto.

Undress AI Tool
Gambar buka pakaian secara percuma

Clothoff.io
Penyingkiran pakaian AI

Video Face Swap
Tukar muka dalam mana-mana video dengan mudah menggunakan alat tukar muka AI percuma kami!

Artikel Panas

Alat panas

Notepad++7.3.1
Editor kod yang mudah digunakan dan percuma

SublimeText3 versi Cina
Versi Cina, sangat mudah digunakan

Hantar Studio 13.0.1
Persekitaran pembangunan bersepadu PHP yang berkuasa

Dreamweaver CS6
Alat pembangunan web visual

SublimeText3 versi Mac
Perisian penyuntingan kod peringkat Tuhan (SublimeText3)

Topik panas

Java 8 memperkenalkan API Stream, menyediakan cara yang kuat dan ekspresif untuk memproses koleksi data. Walau bagaimanapun, soalan biasa apabila menggunakan aliran adalah: bagaimana untuk memecahkan atau kembali dari operasi foreach? Gelung tradisional membolehkan gangguan awal atau pulangan, tetapi kaedah Foreach Stream tidak menyokong secara langsung kaedah ini. Artikel ini akan menerangkan sebab -sebab dan meneroka kaedah alternatif untuk melaksanakan penamatan pramatang dalam sistem pemprosesan aliran. Bacaan Lanjut: Penambahbaikan API Java Stream Memahami aliran aliran Kaedah Foreach adalah operasi terminal yang melakukan satu operasi pada setiap elemen dalam aliran. Niat reka bentuknya adalah

PHP adalah bahasa skrip yang digunakan secara meluas di sisi pelayan, terutamanya sesuai untuk pembangunan web. 1.PHP boleh membenamkan HTML, memproses permintaan dan respons HTTP, dan menyokong pelbagai pangkalan data. 2.PHP digunakan untuk menjana kandungan web dinamik, data borang proses, pangkalan data akses, dan lain -lain, dengan sokongan komuniti yang kuat dan sumber sumber terbuka. 3. PHP adalah bahasa yang ditafsirkan, dan proses pelaksanaan termasuk analisis leksikal, analisis tatabahasa, penyusunan dan pelaksanaan. 4.Php boleh digabungkan dengan MySQL untuk aplikasi lanjutan seperti sistem pendaftaran pengguna. 5. Apabila debugging php, anda boleh menggunakan fungsi seperti error_reporting () dan var_dump (). 6. Mengoptimumkan kod PHP untuk menggunakan mekanisme caching, mengoptimumkan pertanyaan pangkalan data dan menggunakan fungsi terbina dalam. 7

PHP dan Python masing -masing mempunyai kelebihan sendiri, dan pilihannya harus berdasarkan keperluan projek. 1.Php sesuai untuk pembangunan web, dengan sintaks mudah dan kecekapan pelaksanaan yang tinggi. 2. Python sesuai untuk sains data dan pembelajaran mesin, dengan sintaks ringkas dan perpustakaan yang kaya.

PHP sesuai untuk pembangunan web, terutamanya dalam pembangunan pesat dan memproses kandungan dinamik, tetapi tidak baik pada sains data dan aplikasi peringkat perusahaan. Berbanding dengan Python, PHP mempunyai lebih banyak kelebihan dalam pembangunan web, tetapi tidak sebaik python dalam bidang sains data; Berbanding dengan Java, PHP melakukan lebih buruk dalam aplikasi peringkat perusahaan, tetapi lebih fleksibel dalam pembangunan web; Berbanding dengan JavaScript, PHP lebih ringkas dalam pembangunan back-end, tetapi tidak sebaik JavaScript dalam pembangunan front-end.

PHP dan Python masing -masing mempunyai kelebihan sendiri dan sesuai untuk senario yang berbeza. 1.PHP sesuai untuk pembangunan web dan menyediakan pelayan web terbina dalam dan perpustakaan fungsi yang kaya. 2. Python sesuai untuk sains data dan pembelajaran mesin, dengan sintaks ringkas dan perpustakaan standard yang kuat. Apabila memilih, ia harus diputuskan berdasarkan keperluan projek.

Kapsul adalah angka geometri tiga dimensi, terdiri daripada silinder dan hemisfera di kedua-dua hujungnya. Jumlah kapsul boleh dikira dengan menambahkan isipadu silinder dan jumlah hemisfera di kedua -dua hujungnya. Tutorial ini akan membincangkan cara mengira jumlah kapsul yang diberikan dalam Java menggunakan kaedah yang berbeza. Formula volum kapsul Formula untuk jumlah kapsul adalah seperti berikut: Kelantangan kapsul = isipadu isipadu silinder Dua jumlah hemisfera dalam, R: Radius hemisfera. H: Ketinggian silinder (tidak termasuk hemisfera). Contoh 1 masukkan Jejari = 5 unit Ketinggian = 10 unit Output Jilid = 1570.8 Unit padu menjelaskan Kirakan kelantangan menggunakan formula: Kelantangan = π × r2 × h (4

Sebab mengapa PHP adalah timbunan teknologi pilihan untuk banyak laman web termasuk kemudahan penggunaannya, sokongan komuniti yang kuat, dan penggunaan yang meluas. 1) Mudah dipelajari dan digunakan, sesuai untuk pemula. 2) Mempunyai komuniti pemaju yang besar dan sumber yang kaya. 3) Digunakan secara meluas dalam platform WordPress, Drupal dan lain -lain. 4) Mengintegrasikan dengan ketat dengan pelayan web untuk memudahkan penggunaan pembangunan.

Java ialah bahasa pengaturcaraan popular yang boleh dipelajari oleh pembangun pemula dan berpengalaman. Tutorial ini bermula dengan konsep asas dan diteruskan melalui topik lanjutan. Selepas memasang Kit Pembangunan Java, anda boleh berlatih pengaturcaraan dengan mencipta program "Hello, World!" Selepas anda memahami kod, gunakan gesaan arahan untuk menyusun dan menjalankan program, dan "Hello, World!" Pembelajaran Java memulakan perjalanan pengaturcaraan anda, dan apabila penguasaan anda semakin mendalam, anda boleh mencipta aplikasi yang lebih kompleks.
