"Halo, Amigo! Kami memiliki obat mujarab—obat untuk semua penyakit. Seperti yang telah kita lihat, pergantian benang yang tidak terkendali adalah sebuah masalah."
"Mengapa utas itu sendiri tidak dapat memutuskan kapan harus beralih ke utas berikutnya? Lakukan semua yang perlu mereka lakukan dan kemudian beri tanda, «Saya selesai!»?"
"Mengizinkan utas itu sendiri untuk mengontrol peralihan akan menjadi masalah yang lebih besar. Misalkan Anda memiliki beberapa kode yang ditulis dengan buruk, dan utas tidak pernah menyerahkan CPU. Dulu, begitulah cara kerjanya. Dan itu benar-benar mimpi buruk."
"Oke. Jadi apa solusinya?"
" Memblokir utas lain. Begini cara kerjanya."
Menjadi jelas bahwa utas saling mengganggu ketika mereka mencoba menggunakan objek dan/atau sumber daya bersama . Seperti yang kita lihat pada contoh dengan keluaran konsol: ada satu konsol dan semua keluaran utas ke sana. Ini berantakan.
Jadi objek khusus ditemukan: mutex . Itu seperti tanda di pintu kamar mandi yang bertuliskan «tersedia / ditempati» . Ini memiliki dua status: objek tersedia atau ditempati . Status ini juga disebut «terkunci» dan «tidak terkunci».
Ketika sebuah utas membutuhkan objek yang dibagikan dengan utas lainnya, ia memeriksa mutex yang terkait dengan objek tersebut. Jika mutex tidak terkunci, maka utas menguncinya (menandai sebagai «ditempati») dan mulai menggunakan sumber daya bersama. Setelah utas menyelesaikan tugasnya, mutex dibuka kuncinya (ditandai sebagai «tersedia»).
Jika utas ingin menggunakan objek dan mutex dikunci, utas akan tidur sambil menunggu. Saat mutex akhirnya dibuka oleh utas yang menempati, utas kami akan segera menguncinya dan mulai berjalan. Analogi dengan tanda pintu kamar mandi sangat cocok.
"Jadi, bagaimana cara saya bekerja dengan mutex? Apakah saya perlu membuat objek khusus?"
"Jauh lebih sederhana dari itu. Pencipta Java membangun mutex ini ke dalam kelas Object. Jadi Anda bahkan tidak perlu membuatnya. Itu adalah bagian dari setiap objek. Begini cara kerjanya:"
Kode | Keterangan |
---|---|
|
Metode swap menukar nilai variabel name1 dan name2.
Apa yang mungkin terjadi jika dipanggil dari dua utas sekaligus? |
Eksekusi kode aktual | Kode thread pertama | Kode thread kedua |
---|---|---|
|
|
|
Garis bawah |
---|
Nilai variabel ditukar dua kali, kembali ke tempat asalnya. |
Perhatikan kata kunci yang disinkronkan .
"Ya, apa artinya?"
"Ketika sebuah utas memasuki blok kode yang ditandai sebagai disinkronkan, mesin Java segera mengunci mutex objek yang ditunjukkan dalam tanda kurung setelah kata disinkronkan. Tidak ada utas lain yang dapat memasuki blok ini sampai utas kami meninggalkannya. Segera setelah utas kami keluar blok ditandai disinkronkan, mutex segera dan secara otomatis dibuka dan akan tersedia untuk diperoleh oleh utas lain."
Jika mutex ditempati, maka utas kami akan diam dan menunggu hingga kosong.
"Sangat sederhana dan elegan. Itu solusi yang bagus."
"Ya. Tapi menurutmu apa yang akan terjadi dalam kasus ini?"
Kode | Keterangan |
---|---|
|
Metode swap dan swap2 berbagi mutex yang sama ( objek this ). |
Apa yang terjadi jika satu utas memanggil metode swap dan utas lainnya memanggil metode swap2?
"Karena mutexnya sama, utas kedua harus menunggu hingga utas pertama meninggalkan blok yang disinkronkan. Jadi tidak akan ada masalah dengan akses simultan."
"Bagus, Amigo! Itu jawaban yang benar!"
Sekarang saya ingin menunjukkan bahwa sinkronisasi dapat digunakan untuk menandai tidak hanya blok kode, tetapi juga metode. Inilah artinya:
Kode | Apa yang sebenarnya terjadi |
---|---|
|
|
GO TO FULL VERSION