Bagaimana untuk menganalisis penguncian semak semula dalam bahasa JAVA

王林
Lepaskan: 2023-05-12 08:55:17
ke hadapan
1235 orang telah melayarinya

1. Penguncian diperiksa dua kali

Dalam pembangunan program, kadangkala perlu menangguhkan beberapa operasi pemulaan objek berkos tinggi dan hanya memulakannya apabila objek ini digunakan kes, anda boleh Gunakan penguncian yang disemak dua kali untuk menangguhkan operasi pemulaan objek. Penguncian semak dua kali ialah corak reka bentuk perisian yang direka untuk mengurangkan persaingan dan penyegerakan overhed dalam sistem serentak Berdasarkan corak tunggal biasa, ia mula-mula menentukan sama ada objek telah dimulakan, dan kemudian memutuskan sama ada untuk menguncinya. Walaupun penguncian yang disemak dua kali menyelesaikan masalah yang terdedah kepada ralat dan tidak selamat daripada corak tunggal biasa dalam persekitaran berbilang benang, masih terdapat beberapa bahaya tersembunyi. Berikut mengambil kod sumber bahasa JAVA sebagai contoh untuk menganalisis punca dan kaedah pembaikan kecacatan penguncian semak semula.

2. Penguncian semakan dua kaliBahaya

Pengunci semakan dua kali tidak mempunyai kesan dalam persekitaran berbilang benang persekitaran, disebabkan oleh Benang akan menukar pelaksanaan pada bila-bila masa Apabila arahan disusun semula, objek tidak dibuat seketika, mengakibatkan ralat panggilan program.

3. Kod sampel

Sampel datang daripada Samate Juliet Test Suite untuk Java v1.3 (https://samate.nist.gov/SARD/testsuite. php ), nama fail sumber: CWE609_Double_Checked_Locking__Servlet_01.java.

3.1 Kod Kecacatan

Bagaimana untuk menganalisis penguncian semak semula dalam bahasa JAVA

Barisan kod di atas 23-38, atur cara mula-mula menentukan sama ada stringBad adalah batal, jika Jika tidak, kembalikan objek String terus, dengan itu mengelakkan sumber yang diperlukan untuk memasuki blok synchronized. Gunakan kata kunci stringBad untuk mengelak daripada mencipta objek synchronized beberapa kali dalam persekitaran berbilang benang apabila String adalah batal. Apabila kod sebenarnya dijalankan, ralat mungkin masih berlaku dalam kod di atas.

Untuk baris 33, penciptaan objek stringBad dan operasi tugasan dilakukan dalam dua langkah. Tetapi JVM tidak menjamin susunan kedua-dua operasi ini. Apabila arahan disusun semula, JVM akan mula-mula menetapkan nilai yang menunjuk ke alamat memori, dan kemudian memulakan objek stringBad. Jika terdapat dua utas pada masa ini, kedua-dua utas memasuki baris 27 pada masa yang sama. Thread 1 mula-mula memasuki blok synchronized dan oleh kerana stringBad adalah batal, ia melaksanakan baris 33. Apabila JVM menyusun semula arahan, JVM mula-mula memperuntukkan memori kosong bagi contoh dan menetapkannya kepada stringBad, tetapi objek stringBad masih belum digunakan, dan kemudian benang 1 meninggalkan blok synchronized. Apabila benang 2 memasuki blok synchronized, memandangkan stringBad bukan batal pada masa ini, objek yang tidak segera dikembalikan secara langsung (hanya nilai alamat memori, objek sebenarnya tidak dimulakan). Apabila urutan 2 berikutnya memanggil program untuk beroperasi pada objek stringBad, objek pada masa ini belum dimulakan, jadi ralat berlaku.

Gunakan 360 ​​Code Guard untuk mengesan kod sampel di atas Anda boleh mengesan kecacatan "double check lock" dan tahap paparan adalah sederhana. Laporkan kecacatan pada baris 27 kod, seperti ditunjukkan dalam Rajah 1:


Bagaimana untuk menganalisis penguncian semak semula dalam bahasa JAVA

Rajah 1: Contoh pengesanan "Double Check Lock"

3.2 Betulkan kod

Bagaimana untuk menganalisis penguncian semak semula dalam bahasa JAVA

Dalam kod pembaikan di atas, gunakan kata kunci volatile pada baris 23 untuk mengubah suai pembolehubah tunggal stringBad. volatile sebagai kata kunci arahan memastikan arahan tidak akan ditinggalkan kerana pengoptimuman pengkompil dan memerlukan bacaan terus nilai setiap kali.

Disebabkan pengoptimuman pengkompil, pelaksanaan sebenar kod mungkin berbeza daripada pesanan yang kami tulis. Pengkompil hanya menjamin bahawa hasil pelaksanaan program adalah sama dengan kod sumber, tetapi tidak menjamin bahawa susunan arahan sebenar adalah sama dengan kod sumber. sebaik sahaja persekitaran berbilang benang diperkenalkan, gangguan jenis ini boleh menyebabkan masalah yang serius. Kata kunci volatile boleh menyelesaikan masalah ini secara semantik Perlu diingat bahawa larangan fungsi pengoptimuman penyusunan semula arahan volatile telah dilaksanakan selepas Java 1.5, jadi versi sebelum 1.5 masih tidak selamat, walaupun ia digunakan volatile. Kata kunci.

Gunakan 360 ​​Code Guard untuk mengesan kod yang dibaiki, dan anda boleh melihat bahawa kecacatan "double check lock" tidak lagi wujud. Seperti yang ditunjukkan dalam Rajah 2:


Bagaimana untuk menganalisis penguncian semak semula dalam bahasa JAVA

Rajah 2: Hasil pengesanan selepas pembaikan

4 >

Untuk mengelakkan penguncian semak semula, anda perlu memberi perhatian kepada perkara berikut:

(1) Gunakan kata kunci yang tidak menentu untuk mengelakkan penyusunan semula arahan, tetapi penyelesaian ini memerlukan JDK5 atau lebih tinggi, kerana ia digunakan bermula dari JDK5 Spesifikasi model memori JSR-133 baharu, yang meningkatkan semantik yang tidak menentu.

(2) Penyelesaian berdasarkan permulaan kelas.

JVM akan melaksanakan pemulaan kelas semasa fasa pemulaan kelas (iaitu, selepas Kelas dimuatkan dan sebelum ia digunakan oleh utas). Semasa permulaan kelas pelaksanaan, JVM akan memperoleh kunci. Kunci ini boleh menyegerakkan permulaan kelas yang sama dengan berbilang benang. Bagaimana untuk menganalisis penguncian semak semula dalam bahasa JAVA

Atas ialah kandungan terperinci Bagaimana untuk menganalisis penguncian semak semula dalam bahasa JAVA. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Label berkaitan:
sumber:yisu.com
Kenyataan Laman Web ini
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn
Tutorial Popular
Lagi>
Muat turun terkini
Lagi>
kesan web
Kod sumber laman web
Bahan laman web
Templat hujung hadapan