Praktik terbaik untuk sinkronisasi utas .Net

Sinkronisasi adalah konsep yang digunakan untuk mencegah beberapa utas mengakses sumber daya bersama secara bersamaan. Anda dapat menggunakannya untuk mencegah beberapa utas memanggil properti atau metode suatu objek secara bersamaan. Yang perlu Anda lakukan hanyalah menyinkronkan blok kode yang mengakses sumber daya bersama atau menyinkronkan panggilan ke properti dan anggota objek sehingga pada titik waktu tertentu hanya satu utas yang dapat memasuki bagian penting.

Artikel ini menyajikan diskusi tentang konsep yang terkait dengan sinkronisasi dan keamanan utas di .Net dan praktik terbaik yang terlibat.

Kunci eksklusif

Penguncian eksklusif digunakan untuk memastikan bahwa pada titik waktu tertentu, satu dan hanya satu utas yang dapat memasuki bagian kritis. Anda perlu menggunakan salah satu dari berikut ini untuk menerapkan kunci eksklusif di aplikasi Anda.

  • Kunci - ini adalah pintasan sintaksis untuk metode statis kelas Monitor dan digunakan untuk mendapatkan kunci eksklusif pada sumber daya bersama
  • Mutex - mirip dengan kata kunci kunci kecuali bahwa itu dapat bekerja di banyak proses
  • SpinLock - digunakan untuk mendapatkan kunci eksklusif pada sumber daya bersama dengan menghindari overhead pengalih konteks utas

Anda dapat menggunakan metode statis kelas Monitor atau kata kunci kunci untuk menerapkan keamanan thread dalam aplikasi Anda. Baik anggota statis kelas Monitor dan kata kunci kunci dapat digunakan untuk mencegah akses bersamaan ke sumber daya bersama. Kata kunci kunci hanyalah cara pintas untuk mengimplementasikan sinkronisasi. Namun, saat Anda perlu melakukan operasi kompleks dalam aplikasi multithread, metode Wait () dan Pulse () dari kelas Monitor dapat berguna.

Cuplikan kode berikut menggambarkan bagaimana Anda dapat mengimplementasikan sinkronisasi menggunakan kelas Monitor.

private static readonly object lockObj = new object();

        static void Main(string[] args)

        {

            Monitor.Enter(lockObj);

                       try

            {

               //Some code

            }

                  finally

            {

                Monitor.Exit(lockObj);

            }

        }

Kode yang setara dengan menggunakan kata kunci kunci akan terlihat seperti ini:

    private static readonly object lockObj = new object();

        static void Main(string[] args)

        {  

            try

            {

                lock(lockObj)

                {

                    //Some code

                }             

            }

            finally

            {

                //You can release any resources here

            }

        }

Anda dapat memanfaatkan kelas Mutex untuk mengimplementasikan sinkronisasi yang dapat menjangkau seluruh proses. Perhatikan bahwa mirip dengan pernyataan kunci, kunci yang diperoleh Mutex hanya dapat dilepaskan dari utas yang sama yang digunakan untuk mendapatkan kunci. Mendapatkan dan melepaskan kunci menggunakan Mutex relatif lebih lambat daripada melakukan hal yang sama menggunakan pernyataan kunci.

Ide utama di balik SpinLock adalah untuk meminimalkan biaya yang terlibat dalam peralihan konteks antar utas - jika utas dapat menunggu atau berputar selama beberapa waktu hingga dapat memperoleh kunci pada sumber daya bersama, overhead yang terlibat dalam peralihan konteks antar utas dapat dihindari . Ketika bagian kritis melakukan sedikit pekerjaan, itu bisa menjadi kandidat yang baik untuk SpinLock.

Kunci non-eksklusif

Anda dapat memanfaatkan penguncian non-eksklusif untuk membatasi konkurensi. Untuk menerapkan kunci non-eksklusif, Anda dapat menggunakan salah satu dari berikut ini.

  • Semaphore - digunakan untuk membatasi jumlah utas yang dapat memiliki akses ke sumber daya bersama secara bersamaan. Intinya, ini digunakan untuk membatasi jumlah konsumen untuk sumber daya bersama tertentu secara bersamaan.
  • SemaphoreSlim - alternatif yang cepat dan ringan untuk kelas Semaphore untuk menerapkan kunci non-eksklusif.
  • ReaderWriterLockSlim - kelas ReaderWriterLockSlim diperkenalkan di .Net Framework 3.5 sebagai pengganti kelas ReaderWriterLock.

Anda dapat menggunakan kelas ReaderWriterLockSlim untuk mendapatkan kunci non-eksklusif pada sumber daya bersama yang perlu sering dibaca tetapi pembaruan yang jarang. Jadi, alih-alih kunci yang saling eksklusif pada sumber daya bersama yang memerlukan pembacaan sering dan pembaruan yang jarang, Anda dapat menggunakan kelas ini untuk memperoleh kunci baca pada sumber daya bersama dan kunci tulis eksklusif di atasnya.

Kebuntuan

Anda harus menghindari penggunaan pernyataan kunci pada jenis atau pernyataan penggunaan seperti kunci (ini) untuk mengimplementasikan sinkronisasi dalam aplikasi Anda karena hal ini dapat mengakibatkan kebuntuan. Perhatikan bahwa kebuntuan juga dapat muncul jika Anda memegang kunci yang diperoleh pada sumber daya bersama untuk jangka waktu yang lebih lama. Anda tidak boleh menggunakan tipe yang tidak dapat diubah dalam pernyataan kunci Anda. Sebagai contoh, Anda harus menghindari penggunaan objek string sebagai kunci dalam pernyataan kunci Anda. Anda harus menghindari penggunaan pernyataan kunci pada tipe publik - ini adalah praktik yang baik untuk mengunci objek pribadi atau dilindungi yang tidak diinternir. Intinya, situasi kebuntuan terjadi ketika beberapa utas menunggu satu sama lain untuk melepaskan kunci pada sumber daya bersama. Anda dapat merujuk ke artikel MSDN ini untuk mengetahui lebih lanjut tentang kebuntuan.