Akankah kode berikut mengakibatkan kebuntuan menggunakan C # di .NET?
class MyClass
{
private object lockObj = new object();
public void Foo()
{
lock(lockObj)
{
Bar();
}
}
public void Bar()
{
lock(lockObj)
{
// Do something
}
}
}
Jawaban:
Tidak, tidak selama Anda mengunci objek yang sama. Kode rekursif secara efektif sudah memiliki kunci sehingga dapat terus berlanjut tanpa hambatan.
lock(object) {...}
adalah singkatan dari penggunaan kelas Monitor . Seperti yang ditunjukkan Marc ,Monitor
memungkinkan masuk kembali , jadi upaya berulang untuk mengunci objek di mana utas saat ini sudah memiliki kunci akan berfungsi dengan baik.Jika Anda mulai mengunci objek yang berbeda , saat itulah Anda harus berhati-hati. Beri perhatian khusus pada:
Jika Anda melanggar salah satu aturan ini, Anda dijamin akan mendapatkan masalah kebuntuan di beberapa titik .
Berikut adalah satu halaman web bagus yang menjelaskan sinkronisasi utas di .NET: http://dotnetdebug.net/2005/07/20/monitor-class-avoiding-deadlocks/
Selain itu, kunci objek sesedikit mungkin. Pertimbangkan untuk menerapkan kunci berbutir kasar jika memungkinkan. Idenya adalah bahwa jika Anda dapat menulis kode Anda sedemikian rupa sehingga ada grafik objek dan Anda dapat memperoleh kunci pada akar grafik objek tersebut, maka lakukanlah. Ini berarti Anda memiliki satu kunci pada objek root tersebut dan oleh karena itu tidak perlu terlalu mengkhawatirkan urutan di mana Anda memperoleh / melepaskan kunci.
(Satu catatan lagi, contoh Anda secara teknis tidak rekursif. Agar menjadi rekursif,
Bar()
harus memanggil dirinya sendiri, biasanya sebagai bagian dari iterasi.)sumber
Nah,
Monitor
memungkinkan masuk kembali, jadi Anda tidak bisa menemui jalan buntu ... jadi tidak: seharusnya tidaksumber
Jika utas sudah memegang kunci, maka utas tidak akan menghalangi dirinya sendiri. Kerangka .Net memastikan hal ini. Anda hanya perlu memastikan bahwa dua utas tidak mencoba untuk mendapatkan dua kunci yang sama di luar urutan dengan jalur kode apa pun.
Benang yang sama dapat memperoleh kunci yang sama beberapa kali, tetapi Anda harus memastikan Anda melepaskan kunci dengan frekuensi yang sama seperti saat Anda memperolehnya. Tentu saja, selama Anda menggunakan kata kunci "kunci" untuk melakukannya, ini terjadi secara otomatis.
sumber
Tidak, kode ini tidak akan memiliki kunci buntu. Jika Anda benar-benar ingin membuat kebuntuan, yang paling sederhana membutuhkan setidaknya 2 sumber daya. Pertimbangkan skenario anjing dan tulang. 1. Seekor anjing memiliki kendali penuh atas 1 tulang sehingga anjing lain harus menunggu. 2. Minimal 2 anjing dengan 2 tulang diperlukan untuk menciptakan kebuntuan saat mereka mengunci tulang masing-masing dan mencari tulang orang lain juga.
.. seterusnya dan seterusnya n anjing dan m tulang dan menyebabkan kebuntuan yang lebih canggih.
sumber