Jawaban:
Karena metode statis tidak memiliki objek terkait, akankah kata kunci yang disinkronkan mengunci di kelas, bukan objek?
Iya. :)
this
apakah kunci diperoleh pada metode instan-, mohon perbaiki Oscar.
Hanya untuk menambahkan sedikit detail pada jawaban Oscar (menyenangkan ringkas!), Bagian yang relevan pada Spesifikasi Bahasa Jawa adalah 8.4.3.6, 'Metode yang disinkronkan' :
Metode yang disinkronkan memperoleh monitor ( §17.1 ) sebelum dijalankan. Untuk metode kelas (statis), monitor yang terkait dengan objek Kelas untuk kelas metode digunakan. Untuk metode instan, monitor yang terkait dengan ini (objek yang digunakan metode ini) digunakan.
Satu hal yang Anda harus berhati-hati (beberapa programmer umumnya jatuh dalam perangkap itu) adalah bahwa tidak ada hubungan antara metode statis yang disinkronkan dan metode non-statis yang disinkronkan, yaitu:
class A {
static synchronized f() {...}
synchronized g() {...}
}
Utama:
A a = new A();
Utas 1:
A.f();
Utas 2:
a.g();
f () dan g () tidak disinkronkan satu sama lain dan dengan demikian dapat mengeksekusi secara bersamaan.
synchronized (MyClass.class) {...}
,.
Kecuali Anda menerapkan g () sebagai berikut:
g() {
synchronized(getClass()) {
...
}
}
Saya menemukan pola ini berguna juga ketika saya ingin menerapkan saling pengecualian antara berbagai contoh objek (yang diperlukan ketika mengakses sumber daya eksternal, misalnya).
getClass()
mengembalikan tipe runtime ; jika Anda mensubclass kelas, maka kelas induk dan kelas anak akan disinkronkan pada kunci yang berbeda. synchronized(MyClass.class)
adalah cara untuk pergi jika Anda perlu memastikan semua contoh menggunakan kunci yang sama.
Lihat halaman dokumentasi oracle tentang Kunci dan Sinkronisasi Intrinsik
Anda mungkin bertanya-tanya apa yang terjadi ketika metode sinkronisasi statis dipanggil, karena metode statis dikaitkan dengan kelas, bukan objek. Dalam kasus ini, utas memperoleh kunci intrinsik untuk objek Kelas yang terkait dengan kelas . Dengan demikian akses ke bidang statis kelas dikendalikan oleh kunci yang berbeda dari kunci untuk instance kelas apa pun .
Metode statis juga memiliki objek terkait. Itu milik file Class.class di JDK toolkit. Ketika file .class dimuat ke dalam ram, Class.class membuat sebuah instance yang disebut objek template.
Misalnya: - ketika Anda mencoba membuat objek dari kelas pelanggan yang sudah ada seperti
Customer c = new Customer();
Kelas Pelanggan memuat ke dalam RAM. Pada saat itu, Class.class di JDK toolkit membuat Objek yang disebut objek Templat dan memuat yang Customer.class ke objek templat itu. Anggota statis dari Customer.class itu menjadi atribut dan metode dalam objek templat itu.
Jadi metode atau atribut statis juga memiliki objek
Contoh di bawah ini memberikan lebih banyak kejelasan antara kelas dan objek kunci, berharap contoh di bawah ini akan membantu orang lain juga :)
Sebagai contoh kita memiliki metode di bawah ini satu memperoleh kelas dan lainnya memperoleh kunci objek:
public class MultiThread {
public static synchronized void staticLock() throws InterruptedException {
for (int i = 0; i < 10; i++) {
Thread.sleep(100);
System.out.println(Thread.currentThread().getName() + " " + i);
}
}
public synchronized void objLock() throws InterruptedException {
for (int i = 0; i < 10; i++) {
Thread.sleep(100);
System.out.println(Thread.currentThread().getName() + " " + i);
}
}
}
Jadi, sekarang kita dapat memiliki skenario berikut:
Ketika utas menggunakan Objek yang sama mencoba mengakses metode objLock
ATAU staticLock
waktu yang sama (yaitu kedua utas mencoba mengakses metode yang sama)
Thread-0 0
Thread-0 1
Thread-0 2
Thread-0 3
Thread-0 4
Thread-1 0
Thread-1 1
Thread-1 2
Thread-1 3
Thread-1 4
Ketika utas menggunakan Objek yang sama mencoba mengakses staticLock
dan objLock
metode waktu yang sama (mencoba mengakses metode yang berbeda)
Thread-0 0
Thread-1 0
Thread-0 1
Thread-1 1
Thread-0 2
Thread-1 2
Thread-1 3
Thread-0 3
Thread-0 4
Thread-1 4
Ketika utas menggunakan Objek berbeda mencoba mengakses staticLock
metode
Thread-0 0
Thread-0 1
Thread-0 2
Thread-0 3
Thread-0 4
Thread-1 0
Thread-1 1
Thread-1 2
Thread-1 3
Thread-1 4
Ketika utas menggunakan Objek berbeda mencoba mengakses objLock
metode
Thread-0 0
Thread-1 0
Thread-0 1
Thread-1 1
Thread-0 2
Thread-1 2
Thread-1 3
Thread-0 3
Thread-0 4
Thread-1 4
Bagi mereka yang tidak terbiasa metode sinkronisasi statis terkunci pada objek kelas misalnya untuk kelas string-nya String.class sementara metode disinkronkan mengunci pada instance saat ini dari Obyek yang dilambangkan dengan kata kunci "this" di Jawa. Karena kedua objek ini berbeda, mereka memiliki kunci yang berbeda sehingga ketika satu utas menjalankan metode tersinkronisasi statis, utas lainnya di java tidak perlu menunggu utas itu kembali, melainkan akan memperoleh kunci terpisah yang ditandai byte .class literal dan masuk ke metode tersinkronisasi statis.