Kode berikut menunjukkan cara menyinkronkan metode kelas tertentu:
Copy kode kodenya sebagai berikut:
paket mitos;
SyncThread kelas publik memperluas Thread
{
sinkronisasi String statis pribadi = "";
tipe metode String pribadi = "";
metode kekosongan statis pribadi (String s)
{
tersinkronisasi (sinkronisasi)
{
sinkronisasi = s;
Sistem.keluar.println;
sementara (benar);
}
}
metode kekosongan publik1()
{
metode("metode1");
}
kekosongan statis publik staticMethod1()
{
metode("metodestatis1");
}
menjalankan kekosongan publik()
{
if (methodType.equals("statis"))
metode statis1();
else if (methodType.equals("nonstatis"))
metode1();
}
SyncThread publik (Tipe metode string)
{
this.methodType = metodeType;
}
public static void main(String[] args) memunculkan Pengecualian
{
SyncThread sample1 = new SyncThread("nonstatis");
SyncThread sample2 = new SyncThread("statis");
sampel1.mulai();
sampel2.mulai();
}
}
Hasil yang berjalan adalah sebagai berikut:
Copy kode kodenya sebagai berikut:
metode1
Metode statis1
Banyak pembaca mungkin terkejut melihat hasil di atas. Dalam kode di atas, metode method1 dan staticMethod1 menggunakan sinkronisasi variabel string statis untuk sinkronisasi. Hanya satu dari dua metode ini yang dapat dieksekusi pada waktu yang sama, dan kedua metode tersebut akan mengeksekusi pernyataan loop tak terbatas pada baris 014. Oleh karena itu, hasil keluaran hanya dapat berupa salah satu dari metode1 dan metode statis1. Tapi program ini mengeluarkan kedua string.
Alasan hasil ini sangat sederhana, kita akan mengetahuinya dengan melihat baris 012. Ternyata nilai sync diubah pada baris ini. Disini saya ingin berbicara tentang tipe String di Java. Tipe String berbeda dari tipe kompleks lainnya di Java. Saat menggunakan variabel tipe String, selama Anda memberikan nilai ke variabel satu kali, Java akan membuat instance baru dari tipe String. Seperti yang ditunjukkan pada kode berikut:
Copy kode kodenya sebagai berikut:
String s = "halo";
Sistem.keluar.println(s.hashCode());
s = "dunia";
Sistem.keluar.println(s.hashCode());
dalam kode di atas. Nilai hashCode dari s pertama dan s yang ditugaskan ulang berbeda. Karena pembuatan instance kelas String tidak memerlukan penggunaan yang baru, saat menyinkronkan variabel tipe String, berhati-hatilah untuk tidak memberikan nilai ke variabel ini, jika tidak, variabel tersebut tidak akan disinkronkan.
Karena instance baru untuk sinkronisasi telah dibuat pada baris 012, dengan asumsi metode1 dieksekusi terlebih dahulu, ketika metode1 mengeksekusi kode pada baris 013, nilai sinkronisasi bukan lagi nilai aslinya, dan metode1 masih mengunci variabel sinkronisasi Nilai awal . Pada saat ini, staticMethod1 dieksekusi ke sinkronisasi (sinkronisasi). Sinkronisasi yang akan dikunci dalam metode staticMethod1 dan sinkronisasi yang dikunci oleh metode metode1 tidak lagi sama. Oleh karena itu, sinkronisasi kedua metode telah dimusnahkan.
Solusi dari permasalahan diatas tentu saja dengan menghilangkan baris 012. Baris ini ditambahkan ke contoh ini hanya untuk mengilustrasikan bahwa ketika menggunakan variabel kelas untuk menyinkronkan metode, jika nilai variabel sinkronisasi diubah di blok tersinkronisasi, sinkronisasi antar metode akan dimusnahkan. Untuk menghindari situasi ini sepenuhnya, Anda dapat menggunakan kata kunci final saat mendefinisikan variabel sinkronisasi. Misalnya baris 005 pada program di atas dapat diubah menjadi bentuk berikut:
Copy kode kodenya sebagai berikut:
sinkronisasi String statis akhir pribadi = "";
Setelah menggunakan kata kunci final, sinkronisasi hanya dapat memberikan nilai ketika sudah ditentukan, dan tidak dapat diubah nanti. Jika sinkronisasi diberi nilai di tempat lain dalam program, program tidak akan dikompilasi. Dalam alat pengembangan seperti Eclipse, perintah akan diberikan langsung di tempat yang salah.
Kita dapat memahami blok tersinkronisasi dari dua perspektif. Jika dipahami dari perspektif metode kelas, metode terkait dapat disinkronkan melalui variabel kelas. Jika Anda memahaminya dari sudut pandang variabel kelas, Anda dapat menggunakan blok tersinkronisasi untuk memastikan bahwa variabel kelas hanya dapat diakses oleh satu metode pada waktu yang sama. Tidak peduli dari sudut mana Anda memahaminya, esensinya tetap sama, yaitu menggunakan variabel kelas untuk mendapatkan kunci sinkronisasi dan mencapai sinkronisasi melalui saling pengecualian kunci sinkronisasi.
Catatan: Saat menggunakan blok tersinkronisasi, Anda harus menyadari bahwa blok tersinkronisasi hanya dapat menggunakan objek sebagai parameternya. Jika tipe variabelnya sederhana (seperti int, char, boolean, dll.), sinkronisasi tidak dapat digunakan untuk sinkronisasi.