Bagikan melalui


Menyinkronkan data untuk multithreading

Ketika beberapa utas dapat melakukan panggilan ke properti dan metode dari satu objek, sangat penting bahwa panggilan tersebut disinkronkan. Jika tidak, satu utas mungkin mengganggu apa yang dilakukan utas lain, dan objek dapat dibiarkan dalam keadaan tidak valid. Kelas yang anggotanya terlindungi dari gangguan tersebut disebut thread-safe.

.NET menyediakan beberapa strategi untuk menyinkronkan akses ke instans dan anggota statis:

  • Wilayah kode yang disinkronkan. Anda dapat menggunakan dukungan kelas atau pengkompilasi Monitor untuk kelas ini untuk menyinkronkan hanya blok kode yang membutuhkannya, meningkatkan performa.

  • Sinkronisasi manual. Anda dapat menggunakan objek sinkronisasi yang disediakan oleh pustaka kelas .NET. Lihat Gambaran Umum Primitif Sinkronisasi, yang mencakup diskusi kelas Monitor.

  • Konteks yang disinkronkan. Khusus aplikasi .NET Framework dan Xamarin, Anda dapat menggunakan SynchronizationAttribute untuk mengaktifkan sinkronisasi otomatis sederhana untuk objek ContextBoundObject.

  • Kelas koleksi di namespace System.Collections.Concurrent. Kelas-kelas ini menyediakan operasi penambahan dan penghapusan bawaan yang disinkronkan. Untuk informasi selengkapnya, lihat Koleksi Thread-Safe.

Runtime bahasa umum menyediakan model utas di mana kelas termasuk dalam sejumlah kategori yang dapat disinkronkan dengan berbagai cara yang berbeda tergantung pada persyaratannya. Tabel berikut ini memperlihatkan dukungan sinkronisasi apa yang disediakan untuk bidang dan metode dengan kategori sinkronisasi tertentu.

Kategori Bidang global Bidang statis Metode statis Bidang instans Metode instans Blok kode tertentu
Tidak Ada Sinkronisasi Tidak No No No No Tidak
Konteks yang Disinkronkan Tidak No No Ya Ya Tidak
Wilayah Kode yang Disinkronkan Tidak Tidak Hanya jika ditandai No Hanya jika ditandai Hanya jika ditandai
Sinkronisasi Manual Manual Manual Manual Manual Manual Manual

Tidak ada sinkronisasi

Ini adalah default untuk objek. Utas apa pun dapat mengakses metode atau bidang apa pun kapan saja. Hanya satu utas pada satu waktu yang harus mengakses objek ini.

Sinkronisasi manual

Pustaka kelas .NET menyediakan sejumlah kelas untuk menyinkronkan utas. Lihat Gambaran Umum Primitif Sinkronisasi.

Wilayah kode yang disinkronkan

Anda dapat menggunakan kata kunci kelas atau pengkompilasi Monitor untuk menyinkronkan blok kode, metode instans, dan metode statis. Tidak ada dukungan untuk bidang statis yang disinkronkan.

Baik Visual Basic maupun C# mendukung penandaan blok kode dengan kata kunci bahasa tertentu, pernyataan lock dalam C# atau pernyataan SyncLock dalam Visual Basic. Ketika kode dijalankan oleh utas, upaya dilakukan untuk memperoleh kunci. Jika kunci telah diperoleh oleh utas lain, utas akan memblokir hingga kunci tersedia. Ketika utas keluar dari blok kode yang disinkronkan, kunci dilepaskan, terlepas dari bagaimana utas keluar dari blok.

Catatan

Dimulai dari C# 13, lock pernyataan mengenali apakah objek terkunci adalah instans System.Threading.Lock dan menggunakan metode untuk membuat wilayah yang disinkronkan EnterScope . lock, ketika target bukan Lock instans, dan SyncLock pernyataan diimplementasikan menggunakan Monitor.Enter dan Monitor.Exit, sehingga metode lain dapat digunakan bersama dengan mereka dalam wilayah yang disinkronkanMonitor.

Anda juga dapat menghias metode dengan MethodImplAttribute yang bernilai MethodImplOptions.Synchronized, yang memiliki efek yang sama seperti menggunakan Monitor atau salah satu kata kunci pengkompilasi untuk mengunci seluruh isi metode.

Thread.Interrupt dapat digunakan untuk memecah utas dari operasi pemblokiran seperti menunggu akses ke wilayah kode yang disinkronkan. Thread.Interrupt juga digunakan untuk memecah utas dari operasi seperti Thread.Sleep.

Penting

Jangan mengunci jenis — yaitu, typeof(MyType) di C#, GetType(MyType) di Visual Basic, atau MyType::typeid di C++ — untuk melindungi metode static (metode Shared dalam Visual Basic). Gunakan objek statis privat sebagai gantinya. Demikian pula, jangan gunakan this dalam C# (Me dalam Visual Basic) untuk mengunci metode instans. Gunakan objek privat sebagai gantinya. Kelas atau instans dapat dikunci oleh kode selain milik Anda, berpotensi menyebabkan kebuntuan atau masalah performa.

Dukungan pengkompilasi

Baik Visual Basic maupun C# mendukung kata kunci bahasa yang menggunakan Monitor.Enter dan Monitor.Exit untuk mengunci objek. Visual Basic mendukung pernyataan SyncLock; C# mendukung pernyataan lock.

Dalam kedua kasus, jika pengecualian ditampilkan di blok kode, kunci yang diperoleh oleh lock atau SyncLock dirilis secara otomatis. Pengkompilasi C# dan Visual Basic memancarkan blok try/finally dengan Monitor.Enter di awal percobaan, dan Monitor.Exit di blok finally. Jika pengecualian dilemparkan di dalam blok lock atau SyncLock, handler finally berjalan untuk memungkinkan Anda melakukan pekerjaan pembersihan.

Konteks yang Disinkronkan

Hanya dalam aplikasi .NET Framework dan Xamarin, Anda dapat menggunakan SynchronizationAttribute pada ContextBoundObject apa pun untuk menyinkronkan semua metode dan bidang instans. Semua objek dalam domain konteks yang sama memiliki kunci yang sama. Beberapa utas diizinkan untuk mengakses metode dan bidang, tetapi hanya satu utas yang diizinkan pada satu waktu.

Lihat juga