Mari kita lihat kode ini:
Impor Java.util.bitset; Thread t1 = utas baru (runnable baru () {public void run () {coba {latch.await (); thread.sleep (1000);} catch (exception ex) {} bs.set (1);}); Thread t2 = utas baru (runnable baru () {public void run () {coba {latch.aWait (); thread.sleep (1000);} catch (exception e) {} bs.set (2);}}) ; :}}Pertanyaannya adalah, apa hasil dari output kode ini? Hasil apa yang bisa di -output?
Mari kita lihat apa yang dilakukan program ini:
Selanjutnya, kita perlu membangun beberapa kasus tes untuk memeriksa perilaku ini. Jelas, salah satunya hanya dapat menjalankan contoh ini, dan kemudian mengamati hasilnya dan menjawab pertanyaan di atas.
Hati -hati bisa membuat kebetulan
Untungnya, kami dapat menggunakan alat. JCStress adalah alat uji untuk menyelesaikan masalah seperti itu.
Kami dapat dengan mudah menulis test case kami sebagai bentuk yang dapat dikenali oleh JCStress. Bahkan, itu telah menyiapkan berbagai antarmuka bagi kami. Kami membutuhkan contoh. Dalam contoh ini, kedua utas tersebut dieksekusi bersama.
Kami menggunakan antarmuka Actor2_arbiter1_teest <Bitset, BooleanResult2>. Kita perlu menemukan Java 8 JVM untuk menjalankannya, tetapi sekarang ini bukan masalah.
Lihatlah implementasi di bawah ini.
Kelas Publik AnexampleTest mengimplementasikan Actor2_arbiter1_test <Bitset, BooleanResult2> {@Override public void actor1 (Bitset S, BooleanResult2 r) {s.set (1);} @Override public void actor2 (Bitet s, BooleanResult2 );} @Override public void arbiter1 (bitset s, booleanresult2 r) {r.r1 = s.get (1); ;} @Override public boolenrsult2 newResult () {return new booleanresult2 ();}}
Sekarang saat menjalankan tes ini, kontrol akan mencoba semua jenis trik untuk mendapatkan semua kombinasi faktor yang memungkinkan yang mendorong tindakan ini: paralel atau non -merger, tidak ada deteksi beban, dan ada berkali -kali dalam satu baris, berkali -kali, Berkali -kali, berkali -kali, berkali -kali, semua hasil yang mungkin akan dicatat.
Ketika Anda ingin tahu bagaimana kode paralel Anda aktif, ini adalah cara yang lebih baik untuk menggali pemikiran kosong dan memikirkan semua detailnya daripada diri Anda sendiri.
Selain itu, untuk menggunakan kenyamanan komprehensif yang dibawa oleh kendala JCStress, kita perlu memberikannya dengan penjelasan hasil yang mungkin.
<Test name = "org.openjdk.jcstress.tests.custom.anexampleTest"> <Kontribusi-by> Oleg Shelajev </contributed-by> <Deskripsi Jika Bitset bekerja dengan baik tanpa sinkronisasi > Match> [true, true] </catch> <apap> Diterima </hargai> <cripence> Melihat semua pembaruan utuh. /Hargai> <cripence> T2 menimpa hasil T1 > </sase> <nmatched> <pecoptry> Terlarang </pructen> <creckrection> Semua kasus lain di bawah tak terhindarkan.
Sekarang, kami siap untuk binatang buas ini untuk mulai meraung.
java -xx:+uncockdiagnosticvmoptions -xx:+whiteboxapi -xx: -resterictcontended -jar tes -custot/target/jcstress.jar -t = ".*anexampetest"
Hasil yang kami dapatkan adalah laporan yang elegan.
Jelas bahwa kita tidak hanya bisa mendapatkan hasil yang diharapkan, yaitu, kedua utas telah menetapkan posisi mereka, tetapi juga menemukan kondisi kompetitif, dan satu utas akan mencakup hasil utas lain.
Bahkan jika Anda melihat hal seperti itu, Anda harus memiliki mentalitas ketenangan "orang -orang gunung memiliki trik mereka sendiri", bukan?
Ngomong -ngomong, jika Anda berpikir tentang cara memodifikasi kode ini, jawabannya adalah dengan hati -hati membaca kelas bitset di Javadoc dan menyadari bahwa itu bukan keamanan utas dan memerlukan sinkronisasi eksternal. Ini dapat dengan mudah dicapai dengan meningkatkan nilai pengaturan blok sinkron.
disinkronkan (bs) {bs.set (1);}