Metode sinkronisasi Java yang paling dasar adalah menggunakan kata kunci yang disinkronkan untuk mengontrol akses bersamaan suatu metode. Setiap metode yang dinyatakan dengan kata kunci yang disinkronkan adalah bagian kritis. Di Java, hanya satu bagian penting dari objek yang sama diizinkan untuk diakses secara bersamaan.
Metode statis memiliki perilaku yang berbeda. Metode statis yang dinyatakan dengan kata kunci yang disinkronkan hanya dapat diakses oleh satu utas eksekusi, tetapi utas lain dapat mengakses metode sinkronisasi non-statis dari objek ini. Ini harus sangat berhati-hati karena dua utas dapat mengakses dua metode yang disinkronkan dari suatu objek secara bersamaan, yaitu salah satunya adalah metode yang disinkronkan statis dan yang lainnya adalah metode sinkronisasi non-statis. Jika kedua metode mengubah data yang sama, kesalahan yang tidak konsisten akan terjadi.
Sintaks dari blok yang disinkronkan adalah sebagai berikut:
Metode public void () {disinkronkan (ekspresi) {}} Ada dua penggunaan kata kunci yang disinkronkan. Satu hanya digunakan dalam definisi metode, dan yang lainnya adalah blok yang disinkronkan. Kami tidak hanya dapat menggunakan sinkronisasi untuk menyinkronkan variabel objek, tetapi Anda juga dapat menggunakan sinkronisasi untuk menyinkronkan metode statis dan metode non-statis di kelas.
Yang pertama: sinkronisasi metode non-statis
Dari sintaks terkait Java, kita dapat mengetahui bahwa menggunakan kata kunci yang disinkronkan untuk mendefinisikan metode akan mengunci metode statis dan metode non-statis yang ditentukan oleh kata kunci synchronizd di kelas, tetapi ini agak sulit untuk dipahami. Jika Anda ingin menyinkronkan blok untuk mencapai efek seperti itu, tidak sulit untuk memahami mengapa efek ini dihasilkan. Jika Anda menggunakan sinkronisasi untuk mengunci semua metode non-statis yang disinkronkan di kelas, Anda hanya perlu menggunakan ini sebagai parameter blok yang disinkronkan untuk masuk ke blok yang disinkronkan. Kodenya adalah sebagai berikut:
tes kelas publik {public void method1 () {disinkronkan (this) {}} public disinkronkan void method2 () {}} tes kelas publik {public void method1 () {disinkron Dalam kode di atas, Method1 menggunakan blok yang disinkronkan, dan metode Method2 menggunakan kata kunci yang disinkronkan untuk menentukan metode. Jika Anda menggunakan instance tes yang sama, selama salah satu dari dua metode ini sedang dieksekusi, metode lain akan diblokir karena mereka belum mendapatkan kunci sinkronisasi. Selain menggunakan ini sebagai parameter blok yang disinkronkan, Anda juga dapat menggunakan tes. Ini sebagai parameter blok yang disinkronkan untuk mencapai efek yang sama.
Dalam menggunakan blok yang disinkronkan di kelas dalam, ini hanya mewakili kelas dalam dan tidak ada hubungannya dengan kelas luar (outerclass). Namun, metode non-statis dalam kelas dalam dan metode non-statis di kelas luar juga dapat disinkronkan. Jika Anda menambahkan metode metode3 ke kelas dalam, Anda juga dapat menyinkronkan dengan dua metode dalam pengujian, kode ini adalah sebagai berikut:
tes kelas publik {class innerclass {public void method3 () {disinkronkan (test.this) {}}} tes kelas publik {class innerclass {public void method3 () {disinkronkan (test.this) {}}}} Metode Method3 dari InnerClass di atas dan metode tes Method1 dan Method2 hanya dapat memiliki satu metode yang dieksekusi secara bersamaan.
Apakah blok yang disinkronkan dieksekusi dengan benar atau blok yang disinkronkan keluar karena pengecualian karena kesalahan program, kunci sinkronisasi yang dipegang oleh blok yang disinkronkan saat ini akan secara otomatis dilepaskan. Oleh karena itu, Anda tidak perlu khawatir tentang kunci sinkronisasi saat menggunakan blok yang disinkronkan.
2. Sinkronisasi metode statis
Karena instance objek tidak harus dibuat saat memanggil metode statis, ini tidak dapat digunakan untuk menyinkronkan metode statis, tetapi harus menggunakan objek kelas untuk menyinkronkan metode statis. Kodenya adalah sebagai berikut:
tes kelas publik {public static void method1 () {disinkronkan (test.class) {}} public static static void method2 () {}} tes kelas publik {public static void Method1 () {Sinkronisasi (test.class) {}} public static static static void Method2 () {{} {} public static static void void Method2Saat menyinkronkan metode statis, Anda dapat menggunakan kelas bidang statis kelas untuk mendapatkan objek kelas. Dalam contoh di atas, hanya ada satu metode eksekusi metode Method1 dan Method2. Selain menggunakan bidang kelas, Anda juga bisa mendapatkan objek kelas melalui metode GetClass () dari instance. Kodenya adalah sebagai berikut:
tes kelas publik {tes tes statis publik; tes publik () {test = ini; } public static void method1 () {disinkronkan (test.getClass ()) {}} tes kelas publik {tes tes public static; tes publik () {test = ini; } public static void method1 () {disinkronkan (test.getClass ()) {}}}
Dalam kode di atas, kami memperoleh instance tes melalui objek statis publik, dan mendapatkan objek kelas melalui metode GetClass dari contoh ini (perhatikan bahwa semua instance kelas diperoleh melalui metode getClass). Kami juga dapat menyinkronkan metode statis dari kelas yang berbeda melalui kelas, kodenya adalah sebagai berikut:
Public Class test1 {public static void method1 () {disinkronkan (test.class) {}}} public class test1 {public static void method1 () {disinkronkan (test.class) {}}}
Catatan: Ketika blok yang disinkronkan digunakan untuk menyinkronkan metode, metode non-statis dapat disinkronkan melalui ini, sedangkan metode statis harus disinkronkan menggunakan objek kelas, tetapi metode non-statis juga dapat disinkronkan dengan menggunakan kelas. Namun, ini tidak dapat digunakan dalam metode statis untuk menyinkronkan metode non-statis. Ini perlu diperhatikan saat menggunakan blok yang disinkronkan.
Catatan
Kata kunci yang disinkronkan akan menurunkan kinerja aplikasi dan oleh karena itu hanya dapat digunakan pada metode yang memerlukan memodifikasi data bersama dalam skenario bersamaan. Jika beberapa utas mengakses metode sinkronisasi yang sama, hanya satu utas yang dapat mengaksesnya dan utas lainnya akan menunggu. Jika deklarasi metode tidak menggunakan kata kunci yang disinkronkan, semua utas dapat menjalankan metode pada saat yang sama, sehingga mengurangi total waktu berjalan. Jika Anda diketahui dipanggil oleh lebih dari satu utas, Anda tidak perlu menyatakannya menggunakan kata kunci yang disinkronkan.
Metode yang dinyatakan disinkronkan dapat disebut secara rekursif. Ketika utas mengakses metode sinkronisasi objek, ia juga dapat memanggil metode sinkronisasi lain dari objek, termasuk metode pelaksanaan, tanpa harus mendapatkan akses ke metode lagi.
Kami dapat melindungi akses ke blok kode (daripada seluruh metode) melalui kata kunci yang disinkronkan. Kata kunci yang disinkronkan harus digunakan seperti ini: sisa metode tetap di luar blok kode yang disinkronkan untuk kinerja yang lebih baik. Akses ke bagian kritis (mis., Blok kode yang hanya dapat diakses oleh satu utas secara bersamaan) harus sesingkat mungkin. Misalnya, dalam pengoperasian memperoleh jumlah orang di sebuah gedung, kami hanya menggunakan kata kunci yang disinkronkan untuk melindungi instruksi untuk memperbarui jumlah orang, dan membuat operasi lain tidak menggunakan data bersama. Saat menggunakan kata kunci yang disinkronkan dengan cara ini, referensi objek harus digunakan sebagai parameter yang masuk. Hanya satu utas yang diizinkan untuk mengakses kode yang disinkronkan ini secara bersamaan. Secara umum, kami menggunakan kata kunci ini untuk merujuk pada objek yang dimiliki metode yang dieksekusi:
disinkronkan (this) {// java code}