Analoginya: suatu benda ibarat sebuah rumah besar, pintunya selalu terbuka. Ada banyak ruangan (alias metode) di sebuah rumah. Ruangan ini terkunci (metode tersinkronisasi) atau tidak terkunci (metode normal). Terdapat kunci di pintu kamar. Kunci ini dapat membuka semua ruangan yang terkunci. Selain itu, saya membandingkan semua thread yang ingin memanggil metode objek ini dengan orang yang ingin memasuki ruangan tertentu di rumah ini. Itu saja, mari kita lihat bagaimana hal-hal ini bekerja satu sama lain.
Di sini pertama-tama kami memperjelas prasyarat kami. Objek memiliki setidaknya satu metode tersinkronisasi, jika tidak, kunci ini tidak ada artinya. Tentu saja, tema kita tidak akan seperti itu.
Seseorang ingin memasuki ruangan yang terkunci, dia datang ke pintu rumah dan melihat kunci di sana (menunjukkan bahwa belum ada orang lain yang mau menggunakan ruangan yang terkunci tersebut). Jadi dia naik, mengambil kunci, dan menggunakan kamar sesuai rencana. Perhatikan bahwa dia mengembalikan kunci segera setelah setiap penggunaan ruangan terkunci. Bahkan jika dia ingin menggunakan dua ruangan terkunci berturut-turut, dia harus mengembalikan kuncinya dan mengembalikannya di antara keduanya.
Oleh karena itu, prinsip penggunaan kunci dalam keadaan normal adalah: "Pinjam saat Anda menggunakannya, dan kembalikan segera setelah Anda menggunakannya."
Saat ini, orang lain dapat menggunakan ruangan yang tidak terkunci tanpa batasan. Satu orang dapat menggunakan satu ruangan, atau dua orang dapat menggunakan satu ruangan. Tetapi jika seseorang ingin memasuki ruangan terkunci, dia harus lari ke pintu dan melihat. Jika Anda memiliki kuncinya, tentu Anda dapat mengambilnya dan pergi. Jika Anda tidak memiliki kuncinya, Anda hanya bisa menunggu.
Jika banyak orang yang menunggu kuncinya, siapa yang akan mendapatkannya terlebih dahulu ketika kuncinya dikembalikan? Tidak dijamin. Seperti orang pada contoh sebelumnya yang ingin menggunakan dua ruangan terkunci berturut-turut, jika ada orang lain yang menunggu kunci saat dia mengembalikan kuncinya, tidak ada jaminan orang tersebut bisa mendapatkannya lagi. (Spesifikasi JAVA dengan jelas menyatakan di banyak tempat bahwa tidak ada jaminan, seperti berapa lama waktu yang dibutuhkan Thread.sleep() untuk kembali berjalan setelah istirahat, thread mana dengan prioritas yang sama akan dieksekusi terlebih dahulu, dan kapan kunci untuk mengakses objek dilepaskan, beberapa utas di kumpulan tunggu akan Utas mana yang mendapat prioritas, dll. Saya pikir keputusan akhir ada di JVM. Alasan mengapa tidak ada jaminan adalah karena ketika JVM membuat keputusan di atas, tidak hanya membuat penilaian berdasarkan suatu kondisi, tetapi berdasarkan banyak kondisi. Jika terlalu banyak kondisi penilaian, hal itu dapat mempengaruhi promosi JAVA hal ini bukannya tidak masuk akal. Bertekad, bukan sepenuhnya tidak pasti, karena komputer itu sendiri berjalan sesuai dengan instruksi. Sekalipun kelihatannya acak, sebenarnya ada aturan yang bisa ditemukan. Siapa pun yang pernah mempelajari komputer pasti tahu nama ilmiah untuk bilangan acak komputer bersifat pseudo-acak. Angka-angka ditulis oleh orang-orang dengan menggunakan metode tertentu, dan tampak acak-acakan. Selain itu, mungkin karena terlalu merepotkan dan tidak ada artinya untuk ditentukan, jadi jika Anda tidak yakin, Anda tidak yakin .)
Mari kita lihat lagi blok kode yang disinkronkan. Ini sedikit berbeda dengan metode sinkronisasi.
1. Dari segi ukuran, blok kode tersinkronisasi lebih kecil dari metode tersinkronisasi. Anda dapat menganggap blok kode yang disinkronkan sebagai ruang di ruangan tidak terkunci yang dipisahkan oleh layar terkunci.
2. Blok kode sinkronisasi juga dapat menentukan kunci objek lain secara manual. Ini seperti menentukan kunci mana yang dapat digunakan untuk membuka kunci layar ini. Anda dapat menggunakan kunci rumah ini; Anda juga dapat menentukan kunci rumah lain untuk membukanya untuk membuka kunci itu. Dapatkan kunci itu dan gunakan kunci rumah itu untuk membuka layar terkunci rumah ini.
Ingatlah bahwa kunci rumah lain yang Anda peroleh tidak menghalangi orang lain untuk memasuki ruangan yang tidak terkunci di rumah tersebut.
Mengapa menggunakan blok kode yang disinkronkan? Saya pikir seharusnya seperti ini: Pertama-tama, bagian sinkronisasi program mempengaruhi efisiensi operasi, dan suatu metode biasanya membuat beberapa variabel lokal terlebih dahulu, dan kemudian melakukan beberapa operasi pada variabel-variabel ini, seperti perhitungan, tampilan, dll. ; dan sinkronisasi mencakup Semakin banyak kode, semakin serius dampaknya terhadap efisiensi. Jadi kami biasanya berusaha menjaga cakupan dampaknya sekecil mungkin. Bagaimana cara melakukannya? Blok kode yang disinkronkan. Kami hanya menyinkronkan bagian-bagian dari suatu metode yang harus disinkronkan, seperti operasi.
Selain itu, blok kode sinkronisasi dapat menentukan kunci. Fitur ini memiliki manfaat tambahan karena menempati kunci suatu objek dalam jangka waktu tertentu. Ingat apa yang saya katakan sebelumnya tentang prinsip penggunaan kunci dalam keadaan normal. Ini bukanlah keadaan yang biasa. Kunci yang Anda peroleh tidak dikembalikan selamanya, tetapi hanya dikembalikan ketika Anda keluar dari blok kode yang disinkronkan.
Mari kita gunakan analogi pria tadi yang ingin menggunakan dua ruangan terkunci berturut-turut. Bagaimana saya bisa terus menggunakan ruangan lain setelah menggunakan satu ruangan? Gunakan blok kode yang disinkronkan. Pertama buat thread lain, buat blok kode sinkronisasi, dan arahkan kunci blok kode tersebut ke kunci rumah. Kemudian mulai thread itu. Selama Anda dapat mengambil kunci rumah saat Anda memasuki blok kode tersebut, Anda dapat menyimpannya hingga Anda keluar dari blok kode tersebut. Dengan kata lain, Anda bahkan dapat melintasi semua ruangan terkunci di ruangan ini, dan bahkan tidur (10*60*1000), tetapi masih ada 1000 utas yang menunggu kunci di pintu. Ini cukup menyenangkan.
Mari kita bahas tentang korelasi antara metode sleep() dan kuncinya. Jika thread terpaksa tidur() setelah mendapatkan kunci dan belum menyelesaikan sinkronisasi konten, kunci tersebut akan tetap ada. Kunci tidak akan dikembalikan sampai dijalankan kembali dan semua konten sinkronisasi selesai. Ingat, pria itu baru saja lelah bekerja dan pergi istirahat. Dia tidak menyelesaikan apa yang ingin dia lakukan. Untuk mencegah orang lain memasuki ruangan dan membuat kekacauan di dalam, dia harus memakai satu-satunya kunci di tubuhnya bahkan saat tidur.
Terakhir, mungkin ada yang bertanya, mengapa kita memerlukan satu kunci untuk membuka setiap pintu, bukan satu kunci untuk setiap pintu? Menurut saya, ini murni masalah kompleksitas. Satu kunci untuk satu pintu tentu lebih aman, namun akan menimbulkan banyak masalah. Pembuatan, penyimpanan, perolehan, pengembalian kunci, dll. Kompleksitasnya dapat meningkat secara geometris seiring dengan meningkatnya jumlah metode sinkronisasi, sehingga sangat mempengaruhi efisiensi. Hal ini dapat dianggap sebagai masalah trade-off. Betapa tidak diinginkannya mengurangi efisiensi untuk meningkatkan sedikit keamanan.