Artikel ini adalah artikel cermin dari terjemahan mesin, silakan klik di sini untuk melompat ke artikel aslinya.

Melihat: 46741|Jawab: 7

[Sumber] Volatile vs. Interlocked vs. kunci

[Salin tautan]
Diposting pada 27/08/2018 14.40.35 | | |
Katakanlah ada kelas yang berisi bidang penghitung int publik yang dapat diakses oleh beberapa utas, dan jumlah ini hanya akan bertambah atau berkurang.

Saat menambahkan bidang ini, manakah dari skema berikut yang harus digunakan, dan mengapa?

  • kunci(ini.loker) ini.penghitung++;
  • Interlocked.Increment(ref this.counter);
  • Ubah pengubah akses penghitung ke volatil publik


Terburuk (tidak ada yang benar-benar berfungsi)

Ubah pengubah akses penghitung ke volatil publik

Pendekatan ini sebenarnya tidak aman sama sekali, dan intinya tentang volatile adalah bahwa beberapa utas yang berjalan pada beberapa CPU menyangga data dan mengatur ulang instruksi yang dieksekusi.

Jika tidak fluktuatif, ketika CPU A meningkat nilai, CPU B perlu menunggu beberapa saat untuk melihat peningkatan nilai, yang dapat menyebabkan masalah.

Jika fluktuatif, itu memastikan bahwa kedua CPU melihat nilai yang sama pada saat yang bersamaan. Tetapi itu tidak menghindari operasi baca dan tulis lintas sektor.

Menambahkan nilai ke variabel sebenarnya membutuhkan tiga langkah

1. Membaca, 2. Tambahkan 3. Tulis

Misalkan utas A membaca nilai penghitung sebagai 1 dan tidak siap untuk meningkat, maka utas B juga membaca nilai penghitung sebagai 1, dan kemudian kedua utas mulai melakukan operasi inkremental dan tulis. Nilai penghitung akhir adalah 2. Ini tidak benar, kedua benang telah melakukan operasi peningkatan, dan hasil yang benar harus 3. Jadi melabelinya sebagai volatil sama sekali tidak aman.

Lebih baik

kunci(ini.loker) ini.penghitung++;

Dengan cara ini aman (ingatlah untuk mengunci di mana pun Anda ingin mengakses this.counter, tentu saja). Ini mencegah utas lain mengeksekusi kode terkunci. Dan itu juga mencegah masalah pengurutan instruksi multi-CPU yang disebutkan di atas. Masalahnya adalah kunci lambat dalam kinerja, dan jika Anda menggunakan kunci di tempat lain yang tidak terkait, itu dapat memblokir utas Anda yang lain.

Terbaik

Interlocked.Increment(ref this.counter);

Ini aman dan sangat efisien. Ini melakukan membaca, meningkatkan, menulis tiga operasi dalam satu atom tanpa terganggu di tengah. Karena tidak memengaruhi kode lain, Anda tidak perlu mengingat kunci di tempat lain. Dan itu juga sangat cepat (seperti yang dikatakan MSDN, pada CPU saat ini, seringkali hanya instruksi).

Tetapi saya tidak sepenuhnya yakin apakah itu juga dapat memecahkan masalah pemesanan instruksi CPU, atau apakah perlu digunakan bersama dengan volatile dan peningkatan ini.

Suplemen: Masalah apa yang diselesaikan dengan baik volatile?

Karena volatile tidak dapat mencegah multithreading, apa yang bisa dilakukannya? Contoh yang baik adalah Anda memiliki dua utas, satu selalu menulis ke variabel, katakanlah variabel ini adalah queneLength, dan yang lainnya selalu membaca data dari variabel ini. Jika queueLenght tidak fluktuatif, utas A dapat membaca 5 kali, tetapi utas B mungkin melihat data tertunda, atau bahkan data dalam urutan yang salah. Salah satu solusinya adalah dengan menggunakan kunci, tetapi dalam hal ini Anda juga bisa menggunakan volatile. Ini memastikan bahwa utas B selalu melihat data terbaru yang ditulis oleh utas A, tetapi logika ini hanya berfungsi jika Anda tidak membacanya saat menulisnya, dan jika Anda tidak menulisnya saat membacanya. Setelah beberapa utas ingin melakukan operasi baca-ubah-tulis, Anda perlu menggunakan Interlocked atau kunci.





Mantan:Metode enkripsi Java MD5
Depan:Linq mengimplementasikan bukan dalam dan dalam kueri bersyarat di SQL
Diposting pada 29/08/2018 16.21.42 |
Halo, kode yang Anda buat sebelumnya yang menggabungkan histogram bertumpuk highcharts dan histogram yang dapat dibor? Saya ingin bertanya apakah Anda dapat mengirim kode yang dapat diedit di antarmuka https://jshare.com.cn/demos/hhhhDz?hc-theme=grid-light?
Diposting pada 29/08/2018 16.22.13 |
Seluruh jaringan hanyalah sumber daya Anda.
Diposting pada 29/08/2018 16.22.55 |
Karena sebelumnya 90 tahun yang lalu tidak bisa meninggalkan pesan. jadi
Diposting pada 29/08/2018 16.40.40 |
Apakah nyaman untuk menambahkan informasi kontak? Berkonsultasi dengan Anda
 Tuan tanah| Diposting pada 15/09/2018 13.10.16 |
private static int safeInstanceCount = 0; Beroperasi dengan atom
System.Threading.Interlocked.Increment(ref safeInstanceCount); Peningkatan diri 1
System.Threading.Interlocked.Decrement(ref safeInstanceCount); Minus diri 1
Diposting pada 21/05/2020 16.43.54 |
Mendukung pemilik untuk berbagi
 Tuan tanah| Diposting pada 11/06/2020 15.00.16 |
1. Konsep

Dalam lingkungan multi-utas, operasi yang tidak terganggu oleh mekanisme penjadwalan utas; Setelah operasi ini dimulai, operasi ini berjalan hingga akhir, tanpa sakelar konteks (beralih ke utas lain) di antaranya.

2. Kelas

System.Threading.Interlocked kelas statis

3. Fungsi yang umum digunakan (lihat sisanya)

1.publik statis int Decrement (ref int lokasi); Kurangi nilai variabel yang ditentukan dalam bentuk operasi atom dan simpan hasilnya

Setara dengan lock(obj){i--; }

2.publik statis int Increment(ref int lokasi); Tingkatkan nilai variabel yang ditentukan dalam bentuk operasi atom dan simpan hasilnya

Setara dengan lock(obj){i++; }
Sanggahan:
Semua perangkat lunak, materi pemrograman, atau artikel yang diterbitkan oleh Code Farmer Network hanya untuk tujuan pembelajaran dan penelitian; Konten di atas tidak boleh digunakan untuk tujuan komersial atau ilegal, jika tidak, pengguna akan menanggung semua konsekuensi. Informasi di situs ini berasal dari Internet, dan sengketa hak cipta tidak ada hubungannya dengan situs ini. Anda harus sepenuhnya menghapus konten di atas dari komputer Anda dalam waktu 24 jam setelah pengunduhan. Jika Anda menyukai program ini, harap dukung perangkat lunak asli, pembelian pendaftaran, dan dapatkan layanan asli yang lebih baik. Jika ada pelanggaran, silakan hubungi kami melalui email.

Mail To:help@itsvse.com