Saya melihat bahwa untuk menggunakan objek yang tidak aman, kami membungkus kode dengan kunci seperti ini:
private static readonly Object obj = new Object();
lock (obj)
{
// thread unsafe code
}
Jadi apa yang terjadi ketika beberapa utas mengakses kode yang sama (mari kita asumsikan bahwa itu berjalan dalam aplikasi web ASP.NET). Apakah mereka antri? Jika demikian, berapa lama mereka akan menunggu?
Apa dampak kinerja karena menggunakan kunci?
Jawaban:
The
lock
Pernyataan diterjemahkan oleh C # 3.0 dengan berikut ini:Di C # 4.0 ini telah berubah dan sekarang dihasilkan sebagai berikut:
Anda dapat menemukan lebih banyak info tentang apa yang
Monitor.Enter
ada di sini . Mengutip MSDN:The
Monitor.Enter
Metode akan menunggu jauh; itu akan tidak waktu keluar.sumber
obj
tanpa seluruh sistem menemui jalan buntu.lock
pernyataan dan Monitor: sehingga Anda dapat melakukan operasi dalam satu utas tanpa harus khawatir tentang utas lain yang mengatasinya.Lebih sederhana dari yang Anda pikirkan.
Menurut Microsoft : Kata
lock
kunci memastikan bahwa satu utas tidak memasukkan bagian kode yang penting sementara utas lainnya ada di bagian kritis. Jika utas lain mencoba memasukkan kode yang dikunci, ia akan menunggu, memblokir, hingga objek dilepaskan.Kata
lock
kunci panggilanEnter
di awal blok danExit
di akhir blok.lock
kata kunci sebenarnya menanganiMonitor
kelas di bagian belakang.Sebagai contoh:
Dalam kode di atas, pertama utas memasuki bagian kritis, dan kemudian akan mengunci
obj
. Ketika utas lain mencoba masuk, ia juga akan mencoba untuk mengunciobj
, yang sudah dikunci oleh utas pertama. Utas kedua harus menunggu utas pertama dirilisobj
. Ketika utas pertama pergi, maka utas lain akan mengunciobj
dan akan memasuki bagian kritis.sumber
Tidak, mereka tidak mengantri, mereka sedang tidur
Pernyataan kunci formulir
di mana x adalah ekspresi dari tipe referensi, tepat setara dengan
Anda hanya perlu tahu bahwa mereka sedang menunggu satu sama lain, dan hanya satu utas akan masuk untuk mengunci blok, yang lain akan menunggu ...
Monitor ditulis sepenuhnya dalam .net sehingga cukup cepat, lihat juga Monitor kelas dengan reflektor untuk lebih jelasnya
sumber
lock
pernyataan berubah sedikit di C # 4: blogs.msdn.com/b/ericlippert/archive/2009/03/06/...Kunci akan memblokir utas lainnya dari mengeksekusi kode yang terkandung dalam blok kunci. Utas harus menunggu sampai utas di dalam blok kunci selesai dan kunci dilepaskan. Ini memang memiliki dampak negatif pada kinerja di lingkungan multithreaded. Jika Anda perlu melakukan ini, Anda harus memastikan kode di dalam blok kunci dapat diproses dengan sangat cepat. Anda harus mencoba menghindari kegiatan mahal seperti mengakses database dll.
sumber
Dampak kinerja tergantung pada cara Anda mengunci. Anda dapat menemukan daftar optimisasi yang baik di sini: http://www.thinkingparallel.com/2007/07/31/10-ways-to-reduce-lock-contention-in-threaded-programs/
Pada dasarnya Anda harus mencoba untuk mengunci sesedikit mungkin, karena itu membuat kode tunggu Anda tertidur. Jika Anda memiliki beberapa perhitungan berat atau kode tahan lama (mis. Unggahan file) di kunci itu mengakibatkan hilangnya kinerja yang sangat besar.
sumber
do { oldValue = thing; newValue = updated(oldValue); } while (CompareExchange(ref thing, newValue, oldValue) != oldValue
]. Bahaya terbesar adalah bahwa jika persyaratan berkembang melampaui apa yang bisa ditangani oleh teknik tersebut, mungkin sulit untuk mengadaptasi kode untuk mengatasinya.Bagian dalam pernyataan kunci hanya dapat dieksekusi oleh satu utas, jadi semua utas lainnya akan menunggu tanpa batas hingga utas yang menahan kunci untuk menyelesaikannya. Ini dapat menyebabkan kebuntuan.
sumber
The
lock
pernyataan diterjemahkan ke panggilan keEnter
danExit
metodeMonitor
.The
lock
pernyataan akan menunggu selamanya untuk objek mengunci akan dirilis.sumber
kunci sebenarnya adalah kelas Monitor tersembunyi .
sumber