Baru-baru ini saya mencoba mengakses kotak teks dari utas (selain utas UI) dan pengecualian dilemparkan. Ia mengatakan sesuatu tentang "kode tidak menjadi thread aman" dan akhirnya saya menulis sebuah delegasi (sampel dari MSDN membantu) dan memanggilnya sebagai gantinya.
Tapi meski begitu saya tidak begitu mengerti mengapa semua kode tambahan itu diperlukan.
Pembaruan: Apakah saya akan mengalami masalah serius jika saya memeriksanya
Controls.CheckForIllegalCrossThread..blah =true
multithreading
thread-safety
definition
Vivek Bernard
sumber
sumber
Race-Condition
Jawaban:
Eric Lippert memiliki posting blog yang bagus berjudul Apa yang Anda sebut "thread safe"?tentang definisi keamanan benang seperti yang ditemukan di Wikipedia.
3 hal penting yang diambil dari tautan:
Layak dibaca!
sumber
Dalam istilah yang paling sederhana, threadsafe berarti aman untuk diakses dari banyak thread. Saat Anda menggunakan beberapa utas dalam sebuah program dan mereka masing-masing mencoba mengakses struktur data atau lokasi umum dalam memori, beberapa hal buruk dapat terjadi. Jadi, Anda menambahkan beberapa kode tambahan untuk mencegah hal-hal buruk tersebut. Misalnya, jika dua orang menulis dokumen yang sama pada saat yang sama, orang kedua yang akan menyimpan akan menimpa pekerjaan orang pertama. Untuk membuatnya aman utas, Anda harus memaksa orang 2 untuk menunggu orang 1 menyelesaikan tugas mereka sebelum mengizinkan orang 2 untuk mengedit dokumen.
sumber
Wikipedia memiliki artikel tentang Keamanan Benang.
Halaman definisi ini (Anda harus melewati iklan - maaf) mendefinisikannya sebagai berikut:
Utas adalah jalur eksekusi suatu program. Program utas tunggal hanya akan memiliki satu utas dan jadi masalah ini tidak muncul. Hampir semua program GUI memiliki beberapa jalur eksekusi dan karenanya utas - setidaknya ada dua, satu untuk memproses tampilan GUI dan memberikan masukan pengguna, dan setidaknya satu lagi untuk benar-benar melakukan operasi program.
Ini dilakukan agar UI tetap responsif saat program bekerja dengan memindahkan proses yang berjalan lama ke thread non-UI. Utas ini dapat dibuat satu kali dan ada selama program berlangsung, atau dibuat begitu saja saat diperlukan dan dihancurkan setelah selesai.
Karena utas ini sering kali perlu melakukan tindakan umum - disk i / o, menampilkan hasil ke layar, dll. - bagian kode ini perlu ditulis sedemikian rupa sehingga dapat menangani panggilan dari beberapa utas, sering kali di waktu yang sama. Ini akan melibatkan hal-hal seperti:
sumber
Sederhananya, thread safe berarti metode atau instance kelas dapat digunakan oleh beberapa thread secara bersamaan tanpa terjadi masalah.
Pertimbangkan metode berikut:
Sekarang utas A dan utas B keduanya ingin menjalankan AddOne (). tetapi A memulai terlebih dahulu dan membaca nilai myInt (0) menjadi tmp. Sekarang untuk beberapa alasan penjadwal memutuskan untuk menghentikan thread A dan menunda eksekusi ke thread B. Thread B sekarang juga membaca nilai myInt (masih 0) ke dalam variabel tmp itu sendiri. Thread B menyelesaikan seluruh metode, jadi pada akhirnya myInt = 1. Dan 1 dikembalikan. Sekarang giliran Thread A lagi. Thread A berlanjut. Dan menambahkan 1 ke tmp (tmp adalah 0 untuk utas A). Dan kemudian simpan nilai ini di myInt. myInt lagi 1.
Jadi dalam hal ini metode AddOne dipanggil dua kali, tetapi karena metode tersebut tidak diimplementasikan dengan cara yang aman untuk thread, nilai myInt bukan 2, seperti yang diharapkan, tetapi 1 karena thread kedua membaca variabel myInt sebelum thread pertama selesai memperbaruinya.
Membuat metode aman untuk benang sangat sulit dalam kasus yang tidak sepele. Dan ada beberapa teknik. Di Java, Anda dapat menandai metode sebagai tersinkronisasi, ini berarti hanya satu thread yang dapat mengeksekusi metode tersebut pada waktu tertentu. Utas lainnya menunggu dalam antrean. Ini membuat thread metode aman, tetapi jika ada banyak pekerjaan yang harus diselesaikan dalam sebuah metode, maka ini akan membuang banyak ruang. Teknik lainnya adalah 'menandai hanya sebagian kecil dari suatu metode sebagai tersinkronisasi'dengan membuat kunci atau semaphore, dan mengunci bagian kecil ini (biasa disebut bagian kritis). Bahkan ada beberapa metode yang diimplementasikan sebagai pengaman utas tanpa kunci, yang berarti bahwa metode itu dibuat sedemikian rupa sehingga banyak utas dapat membalap melalui mereka pada saat yang sama tanpa pernah menimbulkan masalah, ini dapat terjadi jika metode hanya menjalankan satu panggilan atom. Panggilan atom adalah panggilan yang tidak dapat diganggu dan hanya dapat dilakukan oleh satu utas dalam satu waktu.
sumber
Dalam dunia nyata contoh bagi orang awam adalah
Misalkan Anda memiliki rekening bank dengan internet dan mobile banking dan akun Anda hanya memiliki $ 10. Anda melakukan transfer saldo ke rekening lain menggunakan mobile banking, sementara itu, Anda melakukan belanja online menggunakan rekening bank yang sama. Jika rekening bank ini bukan threadsafe, maka bank mengizinkan Anda untuk melakukan dua transaksi pada saat yang sama dan kemudian bank tersebut akan bangkrut.
Threadsafe berarti bahwa status objek tidak berubah jika beberapa thread mencoba mengakses objek secara bersamaan.
sumber
Anda bisa mendapatkan penjelasan lebih lanjut dari buku "Java Concurrency in Practice":
sumber
Sebuah modul aman untuk thread jika ia menjamin dapat mempertahankan invariannya dalam menghadapi penggunaan multi-thread dan penggunaan bersamaan.
Di sini, modul dapat berupa struktur data, kelas, objek, metode / prosedur, atau fungsi. Pada dasarnya potongan kode dan data terkait.
Jaminan berpotensi dibatasi pada lingkungan tertentu seperti arsitektur CPU tertentu, tetapi harus berlaku untuk lingkungan tersebut. Jika tidak ada batasan eksplisit lingkungan, maka biasanya dianggap menyiratkan bahwa itu berlaku untuk semua lingkungan yang kode dapat dikompilasi dan dijalankan.
Modul thread-unsafe dapat berfungsi dengan benar di bawah penggunaan mutli-threaded dan bersamaan, tetapi ini seringkali lebih karena keberuntungan dan kebetulan, daripada desain yang cermat. Meskipun beberapa modul tidak rusak untuk Anda di bawah, itu mungkin rusak saat dipindahkan ke lingkungan lain.
Bug multi-threading seringkali sulit untuk di-debug. Beberapa di antaranya hanya terjadi sesekali, sementara yang lain terwujud secara agresif - ini juga, dapat menjadi spesifik lingkungan. Mereka bisa bermanifestasi sebagai hasil yang salah secara halus, atau jalan buntu. Mereka dapat mengacaukan struktur data dengan cara yang tidak dapat diprediksi, dan menyebabkan bug lain yang tampaknya tidak mungkin muncul di bagian kode yang jauh lainnya. Ini bisa sangat spesifik untuk aplikasi, jadi sulit untuk memberikan gambaran umum.
sumber
Keamanan benang: Program aman benang melindungi datanya dari kesalahan konsistensi memori. Dalam program yang sangat multi-utas, program aman utas tidak menyebabkan efek samping apa pun dengan beberapa operasi baca / tulis dari beberapa utas pada objek yang sama. Utas yang berbeda dapat membagikan dan mengubah data objek tanpa kesalahan konsistensi.
Anda dapat mencapai keamanan thread dengan menggunakan API konkurensi lanjutan. Halaman dokumentasi ini menyediakan konstruksi pemrograman yang baik untuk mencapai keamanan thread.
Lock Objects mendukung idiom penguncian yang menyederhanakan banyak aplikasi bersamaan.
Pelaksana mendefinisikan API tingkat tinggi untuk meluncurkan dan mengelola utas. Implementasi pelaksana yang disediakan oleh java.util.concurrent menyediakan manajemen kumpulan utas yang sesuai untuk aplikasi berskala besar.
Koleksi Bersamaan memudahkan pengelolaan koleksi data yang besar, dan dapat sangat mengurangi kebutuhan sinkronisasi.
Variabel Atom memiliki fitur yang meminimalkan sinkronisasi dan membantu menghindari kesalahan konsistensi memori.
ThreadLocalRandom (di JDK 7) menyediakan pembuatan nomor pseudorandom yang efisien dari beberapa utas.
Mengacu pada java.util.concurrent dan java.util.concurrent.atomic paket juga untuk konstruksi pemrograman lainnya.
sumber
Anda jelas bekerja di lingkungan WinForms. WinForms mengontrol afinitas utas pameran, yang berarti utas tempat mereka dibuat adalah satu-satunya utas yang dapat digunakan untuk mengakses dan memperbaruinya. Itulah mengapa Anda akan menemukan contoh di MSDN dan di tempat lain yang mendemonstrasikan cara mengatur panggilan kembali ke utas utama.
Praktik WinForms normal adalah memiliki satu utas yang didedikasikan untuk semua pekerjaan UI Anda.
sumber
Saya menemukan konsep http://en.wikipedia.org/wiki/Reentrancy_%28computing%29 menjadi apa yang biasanya saya anggap sebagai threading tidak aman yaitu ketika sebuah metode memiliki dan bergantung pada efek samping seperti variabel global.
Misalnya saya telah melihat kode yang diformat angka floating point menjadi string, jika dua di antaranya dijalankan di utas yang berbeda, nilai global decimalSeparator dapat diubah secara permanen menjadi '.'
sumber
Untuk memahami keamanan benang, baca bagian di bawah ini :
sumber