Pertanyaan Java multi-threading & Publikasi yang Aman


Setelah membaca "Java bersamaan dalam prakteknya"dan"OSGI dalam prakteknya"Saya menemukan subjek tertentu yang sangat menarik; Publikasi yang Aman. Berikut ini dari JCIP:

Untuk mempublikasikan objek dengan aman, referensi ke objek dan status objek harus dibuat terlihat oleh utas lainnya pada saat yang bersamaan. Objek yang dibuat dengan benar dapat dipublikasikan dengan aman oleh:

  • Menginisialisasi referensi objek dari a statis penginisialisasi.
  • Menyimpan referensi ke dalamnya menjadi volatil bidang.
  • Menyimpan referensi ke dalamnya menjadi terakhir bidang.
  • Menyimpan referensi ke dalam bidang yang dijaga dengan benar oleh (disinkronkan) kunci.

Pertanyaan pertama saya: berapa banyak pengembang java yang menyadari hal ini (masalah)? Berapa banyak aplikasi java dunia nyata yang benar-benar mengikuti ini, DAN apakah ini benar-benar masalah nyata? Saya memiliki perasaan bahwa 99% dari JVM yang diimplementasikan di luar sana bukanlah "kejahatan", yaitu sebuah thread tidak dijamin (pada kenyataannya praktisnya (hampir) "tidak mungkin") untuk melihat data lama hanya karena referensi tidak mengikuti "idiom publikasi aman" di atas.


32
2018-04-29 11:49


asal


Jawaban:


Secara proporsional, mungkin adil untuk mengatakan bahwa sangat sedikit programmer yang cukup memahami sinkronisasi dan konkurensi. Siapa yang tahu berapa banyak aplikasi server yang ada di luar sana sekarang mengelola transaksi keuangan, rekam medis, catatan kepolisian, telepon dll. Yang penuh dengan bug sinkronisasi dan pada dasarnya bekerja secara tidak sengaja, atau kadang-kadang sangat gagal (tidak pernah mendengar ada orang yang mendapatkan hantu panggilan telepon ditambahkan ke tagihan telepon mereka?) untuk alasan yang tidak pernah benar-benar melihat atau mendapatkan ke bagian bawah.

Publikasi objek adalah masalah khusus karena sering diabaikan, dan itu adalah tempat di mana cukup masuk akal bagi kompiler untuk membuat optimisasi yang dapat menghasilkan perilaku tak terduga jika Anda tidak mengetahuinya: di kode JIT-dikompilasi, menyimpan penunjuk, kemudian menambah dan menyimpan data adalah hal yang sangat wajar untuk dilakukan. Anda mungkin berpikir itu "jahat", tetapi pada tingkat rendah, itu benar-benar bagaimana Anda mengharapkan spesifikasi JVM. (Kebetulan, saya pernah mendengar tentang program kehidupan nyata yang berjalan di JRockit yang menderita masalah ini - itu tidak murni teoritis.)

Jika Anda tahu bahwa aplikasi Anda memiliki bug sinkronisasi tetapi tidak melakukan kesalahan dalam JVM Anda saat ini di perangkat keras Anda saat ini, maka (a) selamat; dan (b), sekarang adalah waktu untuk memulai "berjalan dengan tenang menuju pintu keluar api", memperbaiki kode Anda dan mendidik programmer Anda sebelum Anda perlu meng-upgrade terlalu banyak komponen.


19
2018-04-29 15:21



"Apakah ini benar-benar masalah nyata?"

Ya, tentu saja. Bahkan aplikasi web yang paling sepele harus menghadapi masalah seputar konkurensi. Servlet diakses oleh beberapa utas, misalnya.

Masalah lainnya adalah bahwa threading dan konkurensi sangat sulit untuk ditangani dengan benar. Hampir terlalu sulit. Itulah sebabnya kami melihat tren muncul seperti memori transaksional, dan bahasa seperti Clojure yang semoga membuat konkurensi lebih mudah untuk ditangani. Tapi kita punya cara untuk pergi sebelum ini menjadi arus utama. Jadi kita harus melakukan yang terbaik dengan apa yang kita miliki. Membaca JCip adalah awal yang sangat baik.


4
2018-04-29 16:14



Pertama "publikasi yang aman" sebenarnya bukan idiom (IMO). Itu datang langsung dari bahasa.

Ada beberapa kasus masalah dengan publikasi yang tidak aman, dengan menggunakan NIO misalnya.

Sebagian besar kode Java ditulis dengan sangat buruk. Kode berulir jelas lebih sulit daripada kode baris-of-bisnis rata-rata.


2
2018-04-29 11:58



Ini bukan masalah menjadi "jahat". Saya t aku s masalah nyata, dan akan menjadi lebih jelas dengan munculnya arsitektur multicore di tahun-tahun mendatang. Saya telah melihat bug produksi yang sangat nyata karena sinkronisasi yang tidak tepat. Dan untuk menjawab pertanyaan Anda yang lain, saya akan mengatakan bahwa sangat sedikit programmer yang menyadari masalah ini, bahkan di antara para pengembang "baik" lainnya.


2
2018-04-29 13:32



Saya akan mengatakan sangat sedikit programmer yang jauh dari masalah ini. Kapan contoh kode terakhir yang Anda lihat yang menggunakan kata kunci yang mudah menguap? Namun, sebagian besar yang dikondisikan lain - saya hanya menerima begitu saja sebagai praktik terbaik.

Jika pengembang benar-benar mengabaikan kondisi tersebut, mereka akan dengan cepat menghadapi kesalahan multi-threading.


1
2018-04-29 12:04



Pengalaman saya (berbicara jangka pendek dan konsultasi di banyak jenis lingkungan yang berbeda Sebagian besar aplikasi yang pernah saya lihat) setuju dengan intuisi ini - saya belum pernah melihat seluruh sistem dengan jelas diarsipkan untuk menangani masalah ini dengan hati-hati (well, saya juga hampir tidak pernah melihat seluruh sistem dengan jelas di-archit). Saya telah bekerja dengan sangat, sangat sedikit pengembang yang memiliki pengetahuan yang baik tentang masalah threading.

Terutama dengan aplikasi web, Anda sering dapat lolos dengan ini, atau setidaknya tampaknya lolos begitu saja. Jika Anda memiliki instantiasi berbasis mata air yang mengelola pembuatan objek dan servlet tanpa kewarganegaraan, Anda sering dapat berpura-pura bahwa tidak ada yang namanya sinkronisasi, dan ini semacam tempat banyak aplikasi berakhir. Akhirnya seseorang mulai menempatkan beberapa keadaan bersama di mana itu bukan milik dan 3 bulan kemudian seseorang melihat beberapa kesalahan intermiten yang aneh. Ini sering "cukup baik" bagi banyak orang (selama Anda tidak menulis transaksi perbankan).

Berapa banyak pengembang java yang menyadari masalah ini? Sulit dikatakan, karena sangat bergantung pada tempat Anda bekerja.


1
2018-04-29 13:46