Pengoptimuman kunci
Pengoptimuman kunci di sini terutamanya merujuk kepada pengoptimuman yang disegerakkan oleh JVM.
Kunci putaran
Penyegerakan Mutex ke dalam keadaan menyekat adalah sangat mahal dan harus dielakkan sebanyak mungkin. Dalam kebanyakan aplikasi, data yang dikongsi dikunci untuk tempoh masa yang singkat sahaja. Idea kunci putaran adalah untuk membenarkan benang melakukan gelung sibuk (putaran) untuk tempoh masa apabila meminta kunci data yang dikongsi Jika kunci boleh diperolehi dalam tempoh ini, ia boleh mengelak daripada memasuki keadaan menyekat .
Walaupun kunci putaran boleh mengelak daripada memasuki keadaan menyekat dan mengurangkan overhed, ia memerlukan operasi gelung yang sibuk untuk mengisi masa CPU Ia hanya sesuai untuk senario di mana keadaan kunci data kongsi adalah sangat singkat.
Kunci putaran adaptif telah diperkenalkan dalam JDK 1.6. Adaptif bermakna bilangan putaran tidak lagi tetap, tetapi ditentukan oleh bilangan putaran sebelumnya pada kunci yang sama dan status pemilik kunci.
Penghapusan kunci
Penghapusan kunci merujuk kepada penghapusan kunci pada data kongsi yang dikesan tidak mungkin mempunyai persaingan.
Penghapusan kunci disokong terutamanya melalui analisis melarikan diri Jika data yang dikongsi pada timbunan tidak dapat dilepaskan dan diakses oleh utas lain, maka ia boleh dianggap sebagai data peribadi dan kuncinya boleh dihapuskan.
Untuk beberapa kod yang nampaknya tidak dikunci, banyak kunci sebenarnya ditambah secara tersirat. Sebagai contoh, kod penggabungan rentetan berikut secara tersirat menambah kunci:
String concatString statik awam(String s1, String s2, String s3) { return s1 + s2 + s3; String ialah kelas yang tidak boleh diubah, dan pengkompil akan mengoptimumkan penyambungan String secara automatik. Sebelum JDK 1.5, ia akan ditukar kepada operasi append() berterusan bagi objek StringBuffer:
String static concatString(String s1, String s2, String s3) { StringBuffer sb = new StringBuffer(s1) ; ; }
Terdapat blok penyegerakan dalam setiap kaedah append(). Mesin maya memerhati pembolehubah sb dan dengan cepat mendapati bahawa skop dinamiknya dihadkan dalam kaedah concatString(). Iaitu, sebarang rujukan kepada sb tidak pernah terlepas di luar kaedah concatString() dan tidak boleh diakses oleh utas lain, jadi ia boleh dihapuskan.
Kekasaran kunci
Jika satu siri operasi berturut-turut mengunci dan membuka kunci objek yang sama berulang kali, operasi mengunci yang kerap akan menyebabkan kehilangan prestasi.
Kaedah append() berturut-turut dalam kod sampel dalam bahagian sebelumnya termasuk dalam kategori ini. Jika mesin maya mengesan bahawa objek yang sama dikunci oleh satu siri operasi berpecah-belah, ia akan mengembangkan (kasar) julat penguncian ke luar keseluruhan jujukan operasi. Kod sampel dalam bahagian sebelumnya dilanjutkan dari sebelum operasi append() pertama kepada selepas operasi append() terakhir, supaya ia hanya perlu dikunci sekali.
Kunci ringan
JDK 1.6 memperkenalkan kunci berat sebelah dan kunci ringan, membenarkan kunci mempunyai empat keadaan: tidak berkunci, berat sebelah, terkunci ringan dan terkunci kelas berat).
Kunci berat juga biasanya dirujuk sebagai kunci objek disegerakkan.
Berikut ialah susun atur memori pengepala objek mesin maya HotSpot Data ini dipanggil Mark Word. Bit tag sepadan dengan lima keadaan, yang diberikan dalam jadual keadaan di sebelah kanan. Sebagai tambahan kepada keadaan bertanda untuk gc, empat negeri lain telah diperkenalkan sebelum ini.
Bahagian kiri rajah di bawah ialah timbunan mesin maya benang Terdapat bahagian kawasan yang dipanggil Rekod Kunci, yang dicipta semasa proses menjalankan kunci ringan dan digunakan untuk menyimpan Kata Tanda objek kunci. Di sebelah kanan ialah objek kunci, yang mengandungi Mark Word dan maklumat lain.
Berbanding dengan kunci heavyweight tradisional, kunci ringan menggunakan operasi CAS untuk mengelakkan overhed kunci heavyweight menggunakan mutex. Untuk kebanyakan kunci, tiada persaingan semasa keseluruhan kitaran penyegerakan, jadi tidak perlu menggunakan mutexes untuk penyegerakan Anda boleh menggunakan operasi CAS untuk penyegerakan jika CAS gagal, sebaliknya gunakan mutexes.
Apabila cuba memperoleh objek kunci, jika objek kunci ditanda 0 01, ia bermakna objek kunci berada dalam keadaan tidak berkunci. Pada masa ini, mesin maya mencipta Rekod Kunci dalam tindanan mesin maya benang semasa, dan kemudian menggunakan operasi CAS untuk mengemas kini Kata Tanda objek kepada penuding Rekod Kunci. Jika operasi CAS berjaya, benang memperoleh kunci pada objek dan teg kunci Mark Word objek berubah kepada 00, menunjukkan bahawa objek berada dalam keadaan kunci ringan.
Jika operasi CAS gagal, mesin maya akan terlebih dahulu menyemak sama ada Mark Word objek menghala ke tindanan mesin maya benang semasa Jika ya, ini bermakna benang semasa sudah memiliki objek kunci, dan kemudian ia boleh terus memasuki blok penyegerakan untuk meneruskan pelaksanaan Jika tidak, ini bermakna Objek kunci telah didahulukan oleh utas lain. Jika lebih daripada dua utas bersaing untuk kunci yang sama, kunci ringan tidak lagi berkesan dan perlu dikembangkan menjadi kunci kelas berat.
Kunci berat sebelah
Idea kunci berat sebelah adalah untuk memihak kepada benang pertama untuk memperoleh objek kunci Benang ini tidak lagi perlu melakukan operasi penyegerakan selepas memperoleh kunci, malah operasi CAS tidak lagi diperlukan.
Apabila objek kunci diperoleh oleh benang buat kali pertama, ia memasuki keadaan berat sebelah dan ditandakan sebagai 1 01. Pada masa yang sama, gunakan operasi CAS untuk merekodkan ID benang ke dalam Mark Word Jika operasi CAS berjaya, benang ini tidak perlu melakukan sebarang operasi penyegerakan setiap kali ia memasuki blok penyegerakan yang berkaitan dengan kunci ini.
Apabila utas lain cuba memperoleh objek kunci ini, keadaan bias berakhir Pada masa ini, bias (Batalkan Bias) dibatalkan dan dikembalikan kepada keadaan tidak berkunci atau keadaan kunci ringan.
Atas ialah kandungan terperinci Bagaimana untuk mengoptimumkan kunci Java. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!