Gambaran umum primitif sinkronisasi

.NET menyediakan berbagai jenis yang dapat Anda gunakan untuk menyinkronkan akses ke sumber daya bersama atau mengoordinasikan interaksi utas.

Penting

Gunakan instans primitif sinkronisasi yang sama untuk melindungi akses sumber daya bersama. Jika Anda menggunakan instans primitif sinkronisasi yang berbeda untuk melindungi sumber daya yang sama, Anda akan menghindari perlindungan yang disediakan oleh primitif sinkronisasi.

Kelas WaitHandle dan jenis sinkronisasi kelas ringan

Beberapa primitif sinkronisasi .NET berasal dari kelas System.Threading.WaitHandle, yang merangkum handel sinkronisasi sistem operasi asli dan menggunakan mekanisme sinyal untuk interaksi utas. Kelas-kelas tersebut meliputi:

Dalam .NET Framework, karena WaitHandle berasal dari System.MarshalByRefObject, jenis ini dapat digunakan untuk menyinkronkan aktivitas utas di seluruh batas domain aplikasi.

Dalam .NET Framework, .NET Core, dan .NET 5+, beberapa jenis ini dapat mewakili handel sinkronisasi sistem bernama, yang terlihat di seluruh sistem operasi dan dapat digunakan untuk sinkronisasi antar-proses:

Untuk informasi selengkapnya, lihat referensi API WaitHandle.

Jenis sinkronisasi ringan tidak bergantung pada handel sistem operasi yang mendasar dan biasanya memberikan performa yang lebih baik. Namun, jenis itu tidak dapat digunakan untuk sinkronisasi antar-proses. Gunakan jenis tersebut untuk sinkronisasi utas dalam satu aplikasi.

Beberapa jenis tersebut adalah alternatif untuk jenis yang berasal dari WaitHandle. Misalnya, SemaphoreSlim adalah alternatif ringan untuk Semaphore.

Sinkronisasi akses ke sumber daya bersama

.NET menyediakan berbagai primitif sinkronisasi untuk mengontrol akses ke sumber daya bersama dengan beberapa utas.

Kelas monitor

Kelas System.Threading.Monitor memberi akses yang saling eksklusif ke sumber daya bersama dengan memperoleh atau melepaskan kunci pada objek yang mengidentifikasi sumber daya. Saat kunci ditahan, utas yang menahan kunci dapat kembali memperoleh dan melepas kunci. Utas lain diblokir untuk memperoleh kunci dan metode Monitor.Enter menunggu hingga kunci dilepaskan. Metode Enter ini memperoleh kunci yang dilepaskan. Anda juga dapat menggunakan metode Monitor.TryEnter untuk menentukan jumlah waktu di mana utas mencoba memperoleh kunci. Karena kelas Monitor memiliki afinitas utas, utas yang memperoleh kunci harus melepaskan kunci dengan memanggil metode Monitor.Exit.

Anda dapat mengoordinasikan interaksi utas yang memperoleh kunci pada objek yang sama dengan menggunakan metode Monitor.Wait, Monitor.Pulse, dan Monitor.PulseAll.

Untuk informasi selengkapnya, lihat referensi API Monitor.

Catatan

Gunakan pernyataan lock di C# dan pernyataan SyncLock di Visual Basic untuk menyinkronkan akses ke sumber daya bersama alih-alih menggunakan kelas Monitor secara langsung. Pernyataan tersebut diimplementasikan menggunakan metode Enter dan Exit dan blok try…finally untuk memastikan bahwa kunci yang diperoleh selalu dirilis.

Kelas Mutex

Kelas System.Threading.Mutex, seperti Monitor, memberi akses eksklusif ke sumber daya bersama. Gunakan salah satu metode Mutex.WaitOne yang overload untuk meminta kepemilikan mutex. Seperti Monitor, Mutex memiliki afinitas utas dan utas yang memperoleh mutex harus melepaskannya dengan memanggil metode Mutex.ReleaseMutex.

Tidak seperti Monitor, kelas Mutex dapat digunakan untuk sinkronisasi antar-proses. Untuk melakukannya, gunakan mutex bernama, yang terlihat di seluruh sistem operasi. Untuk membuat instans mutex bernama, gunakan konstruktor Mutex yang menentukan nama. Anda juga dapat memanggil metode Mutex.OpenExisting untuk membuka mutex sistem bernama yang ada.

Untuk informasi selengkapnya, lihat artikel Mutexes dan referensi API Mutex.

SpinLock structure

Struktur System.Threading.SpinLock, seperti Monitor, memberi akses eksklusif ke sumber daya bersama berdasarkan ketersediaan kunci. Saat SpinLock mencoba untuk memperoleh kunci yang tidak tersedia, kunci menunggu dalam perulangan, berulang kali memeriksa sampai kunci tersedia.

Untuk informasi selengkapnya tentang manfaat dan kelemahan menggunakan kunci putar, lihat artikel SpinLock dan referensi API SpinLock.

ReaderWriterLockSlim class

Kelas System.Threading.ReaderWriterLockSlim ini memberi akses eksklusif ke sumber daya bersama untuk menulis dan memungkinkan beberapa utas mengakses sumber daya secara bersamaan untuk dibaca. Anda mungkin ingin menggunakan ReaderWriterLockSlim untuk menyinkronkan akses ke struktur data bersama yang mendukung operasi baca aman utas, tetapi memerlukan akses eksklusif untuk melakukan operasi tulis. Saat utas meminta akses eksklusif (misalnya, dengan memanggil metode ReaderWriterLockSlim.EnterWriteLock), pembaca dan penulis berikutnya meminta blokir sampai semua pembaca yang ada telah keluar dari kunci, dan penulis telah memasukkan dan keluar dari kunci.

Untuk informasi selengkapnya, lihat referensi API ReaderWriterLockSlim.

Kelas Semaphore dan SemaphoreSlim

Kelas System.Threading.Semaphore dan System.Threading.SemaphoreSlim membatasi jumlah utas yang dapat mengakses sumber daya bersama atau kumpulan sumber daya secara bersamaan. Utas tambahan yang meminta sumber daya menunggu hingga utas apa pun merilis semaphore. Karena semaphore tidak memiliki afinitas utas, utas dapat memperoleh semaphore dan satu lagi dapat melepaskannya.

SemaphoreSlim adalah alternatif ringan untuk Semaphore dan hanya dapat digunakan untuk sinkronisasi dalam satu batas proses.

Pada Windows, Anda dapat menggunakan Semaphore untuk sinkronisasi antar-proses. Untuk melakukannya, buat instans Semaphore yang mewakili semaphore sistem bernama dengan menggunakan salah satu konstruktor Semaphore yang menentukan nama atau metode Semaphore.OpenExisting. SemaphoreSlim tidak mendukung semaphores sistem bernama.

Untuk informasi selengkapnya, lihat artikel Semaphore dan SemaphoreSlim dan Semaphore atau referensi API SemaphoreSlim.

Interaksi utas, atau sinyal

Interaksi utas (atau sinyal utas) berarti bahwa utas harus menunggu pemberitahuan, atau sinyal, dari satu atau beberapa utas untuk melanjutkan. Misalnya, jika utas A memanggil metode Thread.Join utas B, utas A diblokir hingga utas B selesai. Primitif sinkronisasi yang dijelaskan di bagian sebelumnya menyediakan mekanisme yang berbeda untuk memberi sinyal: dengan melepas kunci, utas memberi tahu utas lain bahwa ia dapat melanjutkan dengan memperoleh kunci.

Bagian ini menjelaskan konstruksi sinyal tambahan yang disediakan oleh .NET.

Kelas EventWaitHandle, AutoResetEvent, ManualResetEvent, dan ManualResetEventSlim

Kelas System.Threading.EventWaitHandle mewakili peristiwa sinkronisasi utas.

Peristiwa sinkronisasi dapat dalam keadaan tidak bersinyal atau bersinyal. Saat status peristiwa tidak bersinyal, utas yang memanggil overload WaitOne peristiwa diblokir hingga peristiwa disinyalir. Metode EventWaitHandle.Set mengatur status peristiwa ke sinyal.

Perilaku EventWaitHandle yang telah disinyalkan tergantung pada mode resetnya:

Pada Windows, Anda dapat menggunakan EventWaitHandle untuk sinkronisasi antar-proses. Untuk melakukannya, buat EventWaitHandle instans yang mewakili peristiwa sinkronisasi sistem bernama dengan menggunakan salah satu konstruktor EventWaitHandle yang menentukan nama atau EventWaitHandle.OpenExisting metode .

Untuk informasi selengkapnya, lihat artikel EventWaitHandle. Untuk referensi API, lihat EventWaitHandle, AutoResetEvent, ManualResetEvent, dan ManualResetEventSlim.

Kelas CountdownEvent

Kelas System.Threading.CountdownEvent mewakili peristiwa yang menjadi diatur saat jumlahnya adalah nol. Meskipun CountdownEvent.CurrentCount lebih besar dari nol, utas yang memanggil CountdownEvent.Wait diblokir. Panggilan CountdownEvent.Signal untuk mengurangi jumlah peristiwa.

Berbeda dari ManualResetEvent atau ManualResetEventSlim, yang dapat Anda gunakan untuk membuka blokir beberapa utas dengan sinyal dari satu utas, Anda dapat menggunakan CountdownEvent untuk membuka blokir satu atau beberapa utas dengan sinyal dari beberapa utas.

Untuk informasi selengkapnya, lihat artikel CountdownEvent dan referensi API CountdownEvent.

Kelas penghalang

Kelas System.Threading.Barrier mewakili penghalang eksekusi utas. Utas yang memanggil metode Barrier.SignalAndWait memberi sinyal bahwa itu mencapai penghalang dan menunggu sampai utas peserta lain mencapai hambatan. Saat semua utas peserta mencapai penghalang, utas melanjutkan dan hambatan diatur ulang dan dapat digunakan lagi.

Anda mungkin menggunakan Barrier saat satu atau beberapa utas memerlukan hasil utas lain sebelum melanjutkan ke fase komputasi berikutnya.

Untuk informasi selengkapnya, lihat artikel Penghalang dan referensi API Barrier.

Kelas interlocked

Kelas System.Threading.Interlocked ini menyediakan metode statis yang melakukan operasi atom sederhana pada variabel. Operasi atom itu termasuk penambahan, kenaikan dan penurunan, pertukaran dan pertukaran bersyarat yang bergantung pada perbandingan, dan operasi baca dari nilai bilangan bulat 64-bit.

Untuk informasi selengkapnya, lihat referensi API Interlocked.

SpinWait structure

Struktur System.Threading.SpinWait ini menyediakan dukungan untuk menunggu berbasis spin. Anda mungkin ingin menggunakannya saat utas harus menunggu peristiwa disinyalkan atau kondisi terpenuhi, tetapi saat waktu tunggu aktual diperkirakan kurang dari waktu tunggu yang diperlukan dengan menggunakan handel tunggu atau dengan memblokir utas. Menggunakan SpinWait, Anda dapat menentukan waktu yang singkat untuk berputar saat menunggu, lalu menghasilkan (misalnya, dengan menunggu atau tidur) hanya jika kondisi tidak terpenuhi dalam waktu yang ditentukan.

Untuk informasi selengkapnya, lihat artikel SpinWait dan referensi API SpinWait.

Lihat juga