Sinkronisasi mengacu pada multithreading. Blok kode yang disinkronkan hanya dapat dieksekusi oleh satu thread dalam satu waktu. Java mendukung banyak thread untuk dieksekusi. Hal ini dapat mengakibatkan dua atau lebih thread mengakses bidang atau objek yang sama. Sinkronisasi adalah proses yang memungkinkan semua thread paralel dalam suatu program berjalan secara sinkron. Sinkronisasi menghindari kesalahan konsistensi memori yang disebabkan oleh akses yang tidak konsisten ke memori bersama. Ketika suatu metode dideklarasikan sebagai tersinkronisasi, thread memegang monitor untuk objek yang metodenya sedang dijalankan. Jika thread lain menjalankan metode tersinkronisasi, thread Anda akan diblokir hingga thread lain melepaskan monitor. Sinkronisasi dicapai di Java menggunakan kata yang dicadangkan
synchronized
. Anda dapat menggunakannya di kelas Anda dengan mendefinisikan metode atau blok yang disinkronkan. Anda tidak akan dapat menggunakan synchronized
variabel atau atribut dalam definisi kelas.
Penguncian tingkat objek
Ini adalah mekanisme untuk menyinkronkan metode non-statis atau blok kode non-statis sehingga hanya satu thread yang dapat mengeksekusi blok atau metode tertentu pada instance kelas tertentu. Ini harus dilakukan kapan pun Anda perlu membuat thread data tingkat instans aman. Contoh:public class DemoClass{
public synchronized void demoMethod(){}
}
atau
public class DemoClass{
public void demoMethod(){
synchronized (this) {
//other thread safe code
}
}
}
atau
public class DemoClass{
private final Object lock = new Object();
public void demoMethod(){
synchronized (lock) {
//other thread safe code
}
}
}
Penguncian tingkat kelas
Mencegah beberapa thread memasuki blok tersinkronisasi selama eksekusi di salah satu instance kelas yang tersedia. Ini berarti bahwa jika ada 100 instance kelas selama eksekusi suatu programDemoClass
, maka hanya satu thread pada saat itu yang dapat mengeksekusi demoMethod()
salah satu kasus, dan semua kasus lainnya akan diblokir untuk thread lainnya. Ini diperlukan ketika Anda perlu membuat thread data statis aman.
public class DemoClass{
public synchronized static void demoMethod(){}
}
atau
public class DemoClass{
public void demoMethod(){
synchronized (DemoClass.class) {
//other thread safe code
}
}
}
atau
public class DemoClass
{
private final static Object lock = new Object();
public void demoMethod(){
synchronized (lock) {
//other thread safe code
}
}
}
Beberapa Catatan Penting
- Sinkronisasi di Java memastikan bahwa tidak ada dua thread yang dapat menjalankan metode tersinkronisasi secara bersamaan atau paralel.
synchronized
hanya dapat digunakan dengan metode dan blok kode. Metode atau blok ini bisa bersifat statis atau non-statis.- Setiap kali ada thread yang memasuki metode atau blok yang disinkronkan, maka thread tersebut memperoleh kunci dan setiap kali thread keluar dari metode atau blok yang disinkronkan, JVM akan melepaskan kunci tersebut. Kunci dilepaskan bahkan jika thread meninggalkan metode tersinkronisasi setelah selesai karena kesalahan atau pengecualian apa pun.
synchronized
di Java , ini berarti jika metode tersinkronisasi memanggil metode tersinkronisasi lain yang memerlukan kunci yang sama, thread saat ini yang menyimpan kunci tersebut dapat memasuki metode tersebut tanpa memperoleh kunci tersebut.- Синхронизация в Java будет бросать
NullPointerException
если an object используемый в синхронизированном блоке null. Например, в вышеприведенном примере codeа, если замок инициализируется Hownull
, синхронизированный (lock) броситNullPointerException
. - Синхронизированные методы в Java вносят дополнительные затраты на производительность вашего applications. Так что используйте синхронизацию, когда она абсолютно необходима. Кроме того, рассмотрите вопрос об использовании синхронизированных блоков codeа для синхронизации только критических секций codeа.
- Вполне возможно, что и статический и не статический синхронизированные методы могут работать одновременно or параллельно, потому что они захватывают замок на другой an object.
- В соответствии со спецификацией языка вы не можете использовать
synchronized
в конструкторе это приведет к ошибке компиляции. - Не синхронизируйте по не финальному (no final) полю, потому что link, на не финальное поле может измениться в любое время, а затем другой поток может получить синхронизацию на разных an objectх и уже не будет ниHowой синхронизации вообще. Лучше всего использовать класс
String
, который уже неизменяемый и финальный.
GO TO FULL VERSION