Synchronized: apa itu, prinsip kerja dan penggunaan di Java

Penulis: IT Sectr Diterbitkan: 2026-03-19 Waktu membaca: 8 mnt

Synchronized adalah mekanisme sinkronisasi bawaan dalam bahasa Java yang menyediakan akses eksklusif ke bagian kritis kode. Menurut Oracle, 2024, pengubah synchronized menjamin bahwa hanya satu thread yang dapat menjalankan metode atau blok yang ditandai pada satu waktu tertentu. Mekanisme ini didasarkan pada monitor — konsep fundamental sistem operasi yang memastikan pengoperasian aplikasi multithread yang benar di semua tingkat kompleksitas.

Poin utama

  • Synchronized — kata kunci Java untuk akses data yang aman.
  • Monitor objek — mekanisme internal yang mendasari sinkronisasi.
  • Metode synchronized memblokir seluruh metode di tingkat instance atau kelas.
  • Blok synchronized memungkinkan sinkronisasi hanya sebagian kode.
  • Deadlock — salah satu masalah utama dalam sinkronisasi bersarang.

Apa itu synchronized?

Synchronized adalah kata kunci di Java yang menjamin bahwa hanya satu thread pada satu waktu yang menjalankan bagian kode yang dilindungi, mencegah kerusakan data saat akses paralel. Ini muncul di versi pertama Java dan tetap menjadi cara paling sederhana untuk memastikan keamanan thread bagi pengembang di semua tingkat keahlian.

Definisi dan peran di Java

Pengubah synchronized menyelesaikan dua tugas: saling eksklusi (mutual exclusion) dan visibilitas perubahan (visibility). Ketika sebuah thread meninggalkan blok synchronized, semua perubahan dijamin terlihat oleh thread lain yang memasuki blok yang disinkronkan pada objek yang sama.

Synchronized dapat diterapkan ke seluruh metode atau ke blok kode sembarang dengan menentukan objek-monitor. Dalam kedua kasus, JVM menyisipkan instruksi monitorenter dan monitorexit di level bytecode.

Latar belakang kemunculan

Dalam aplikasi multithread tanpa sinkronisasi, terjadi kondisi balapan (race condition) — ketika dua thread secara bersamaan mengubah data yang sama, menyebabkan hasil yang tidak terduga. Synchronized menjadi alat pertama dan utama Java untuk mengatasi masalah ini, menyediakan sintaks deklaratif sederhana yang dapat diakses oleh setiap pengembang.

Bagaimana cara kerja synchronized?

Mekanisme synchronized didasarkan pada konsep monitor — primitif sinkronisasi tingkat tinggi yang tertanam di setiap objek Java. Monitor dikaitkan dengan objek saat pertama kali menggunakan blok synchronized padanya.

Monitor objek

Setiap objek di Java memiliki monitor yang terkait. Ketika sebuah thread memasuki blok synchronized, ia mengambil alih monitor objek. Jika monitor sudah digunakan oleh thread lain, thread tersebut diblokir hingga dibebaskan. Dalam bytecode, ini sesuai dengan pasangan instruksi monitorenter dan monitorexit.

Status penguncian (biased locking)

JVM mengoptimalkan synchronized melalui beberapa tingkat: biased locking (penguncian condong) untuk akses single-thread, lightweight locking (penguncian ringan) saat persaingan rendah, dan heavyweight locking (penguncian berat) saat persaingan intensif dengan partisipasi OS. Tingkat-tingkat ini meningkatkan kinerja tanpa mengubah kode.

java
class Counter {
    private int count = 0;

    public synchronized void increment() {
        count++;
    }

    public synchronized int getCount() {
        return count;
    }
}

Aturan happens-before

Synchronized menetapkan relasi happens-before: semua tindakan dalam thread sebelum meninggalkan blok synchronized terlihat oleh thread lain setelah memasuki blok yang disinkronkan pada objek yang sama. Ini menjamin tidak hanya saling eksklusi, tetapi juga konsistensi data untuk semua thread.

Metode synchronized vs blok

Java menawarkan dua cara untuk menerapkan synchronized: di tingkat metode dan di tingkat blok. Pilihan di antara keduanya mempengaruhi kinerja dan granularitas sinkronisasi.

Metode synchronized

Dengan menandai metode dengan pengubah synchronized, Anda secara otomatis menyinkronkannya pada instance saat ini (untuk metode biasa) atau pada objek Class (untuk metode statis). Ini adalah cara paling sederhana untuk memastikan saling eksklusi, tetapi seringkali berlebihan jika bagian kritis hanya merupakan sebagian kecil dari metode dan kode lainnya tidak memerlukan sinkronisasi.

Blok synchronized

Blok synchronized memberikan kontrol yang tepat: Anda menentukan objek-monitor dan menyinkronkan hanya bagian kode yang diperlukan, meninggalkan sisa metode di luar penguncian. Ini meminimalkan waktu penahanan monitor dan meningkatkan kinerja keseluruhan aplikasi di lingkungan multithread, karena thread lain dapat menjalankan kode yang tidak terkait secara paralel tanpa menunggu pelepasan monitor.

java
class DataProcessor {
    private final Object lock = new Object();

    public void process() {
        // kode di luar seksi kritis - tanpa sinkronisasi
        prepareData()

        synchronized (lock) {
            // hanya blok ini yang dilindungi
            updateSharedState()
        }

        // lanjutan tanpa penguncian
        cleanup()
    }
}
KriteriaMetode synchronizedBlok synchronized
Monitorthis (instance) atau Classobjek apa pun
Granularitasseluruh metodehanya kode yang diperlukan
Keterbacaantinggisedang
Kinerjalebih rendah untuk metode besarlebih tinggi untuk bagian kritis kecil

Synchronized di Android

Dalam pengembangan Android, synchronized banyak digunakan untuk melindungi SharedPreferences, akses database, dan komponen UI. Namun, penggunaannya di thread utama sangat tidak disarankan karena risiko pembekuan antarmuka.

Penggunaan dengan SharedPreferences

SharedPreferences di Android menyediakan keamanan thread dasar, tetapi saat diedit oleh beberapa thread melalui Editor, sinkronisasi eksternal mungkin diperlukan. Blok synchronized dengan objek penguncian terpisah menjamin konsistensi perubahan.

kotlin
class PreferencesManager(private val prefs: SharedPreferences) {
    private val lock = Any()

    fun writeToken(token: String) {
        synchronized (lock) {
            prefs.edit()
                .putString("auth_token", token)
                .apply()
        }
    }
}

Keterbatasan di aplikasi Android

Keterbatasan utama synchronized di Android — pemblokiran thread. Tidak seperti coroutine dengan Mutex, synchronized memblokir seluruh thread sistem. Di thread utama, ini menyebabkan ANR. Dalam pengembangan Android modern, disarankan untuk mengganti synchronized dengan coroutine (suspend Mutex) atau tipe atomik (AtomicInteger).

Alternatif untuk synchronized

Java dan Kotlin modern menawarkan beberapa alternatif untuk synchronized, yang masing-masing menyelesaikan tugas yang sama dengan lebih sedikit keterbatasan atau kinerja yang lebih baik.

Lock dari java.util.concurrent

Antarmuka Lock dengan implementasi ReentrantLock dan ReadWriteLock menyediakan batas waktu, penantian yang dapat diinterupsi, dan beberapa antrian Condition. Ini lebih fleksibel daripada synchronized, tetapi memerlukan pelepasan eksplisit di finally, yang meningkatkan risiko kesalahan karena unlock yang terlupakan.

Kelas atomik

Kelas AtomicInteger, AtomicLong, AtomicReference dan lainnya menggunakan algoritma Lock-Free berbasis CAS (Compare-And-Swap). Mereka secara signifikan lebih cepat daripada synchronized dalam skenario dengan persaingan sedang, karena tidak memblokir thread, melainkan melakukan percobaan ulang optimistis dan tidak memerlukan peralihan konteks oleh kernel OS.

ThreadLocal dan keamanan thread

ThreadLocal menyediakan pendekatan alternatif: setiap variabel ThreadLocal diisolasi dalam lingkup satu thread dan tidak memerlukan sinkronisasi untuk membaca dan menulis. Ini sepenuhnya menghilangkan kebutuhan akan synchronized untuk data yang tidak boleh dibagi antar thread. ThreadLocal secara aktif digunakan dalam framework (Spring, Hibernate) untuk menyimpan konteks transaksi dan sesi.

Coroutine dan pendekatan compose

Dalam proyek Kotlin untuk Android, alternatif untuk synchronized adalah Mutex dari kotlinx.coroutines. Ini tidak memblokir thread sistem operasi, melainkan menangguhkan coroutine hingga penguncian dilepaskan — ini memungkinkan penggunaan thread pool secara efisien dan menghindari ANR saat menunggu lama untuk pelepasan sumber daya.

kotlin
import kotlinx.coroutines.sync.Mutex
import kotlinx.coroutines.sync.withLock

val mutex = Mutex()
var counter = 0

suspend fun safeIncrement() {
    mutex.withLock {
        counter++
    }
}

Kinerja synchronized

Kinerja synchronized telah berubah secara signifikan di versi Java terbaru. Sebelumnya dianggap sebagai mekanisme yang "berat", tetapi JVM modern telah menghilangkan sebagian besar overhead berkat optimalisasi lanjutan dari kompiler JIT. Mari kita lihat secara detail bagaimana mesin virtual mempercepat kode yang disinkronkan saat runtime.

Biased Locking dan Lock Coarsening

Kompiler JIT JVM menerapkan beberapa optimalisasi: biased locking menghilangkan sinkronisasi jika penguncian selalu diambil oleh satu thread; lock coarsening menggabungkan blok synchronized yang berdekatan menjadi satu; lock elimination menghapus sinkronisasi jika objek hanya dapat diakses oleh satu thread. Optimalisasi ini membuat synchronized praktis gratis pada persaingan rendah.

Pengukuran persaingan dan pemilihan optimalisasi

JVM menentukan tingkat persaingan untuk setiap objek: saat tidak ada persaingan, biased locking diaktifkan; saat thread kedua muncul, penguncian beralih ke mode lightweight dengan spin-waiting; dan hanya saat penantian lama — ke heavyweight dengan mutex sistem. Eskalasi ini terjadi secara otomatis dan pengembang tidak perlu memilih strategi secara manual.

Perbandingan dengan Lock dan kelas atomik

Dalam benchmark modern (Java 17+) synchronized menunjukkan kinerja yang sebanding dengan ReentrantLock pada persaingan rendah dan sedang. Pada persaingan tinggi, Lock mungkin memiliki keunggulan berkat antrian penantian yang lebih efisien dengan dukungan batas waktu dan interupsi. Untuk sistem dengan beban tinggi di mana persaingan konstan, ReentrantLock dalam mode fair memberikan perilaku yang lebih dapat diprediksi.

Kelas atomik (AtomicInteger, AtomicReference) tetap menjadi yang tercepat untuk penghitung dan bendera sederhana berkat implementasi Lock-Free pada CAS. Mereka sama sekali tidak memblokir thread — saat konflik, operasi hanya diulang dalam loop. Ini memberikan peningkatan kinerja 3-5 kali lipat dibandingkan dengan synchronized pada operasi kenaikan penghitung dengan 4-8 thread.

Pertanyaan yang sering diajukan

Apa perbedaan antara synchronized dan volatile?

Synchronized menyediakan saling eksklusi dan visibilitas. Volatile hanya menjamin visibilitas perubahan — penulisan ke variabel volatile terlihat oleh semua thread, tetapi tidak mencegah perubahan simultan, artinya tidak melindungi dari kondisi balapan.

Bisakah synchronized menyebabkan deadlock?

Ya, deadlock mungkin terjadi pada sinkronisasi bersarang dengan urutan monitor yang berbeda. Misalnya, satu thread memanggil synchronized(a) { synchronized(b) }, dan yang lain — synchronized(b) { synchronized(a) }. Hindari blok synchronized bersarang atau tetapkan urutan monitor yang tetap.

Apa itu monitor di Java?

Monitor adalah mekanisme sinkronisasi yang terkait dengan setiap objek Java. Ini menjamin bahwa hanya satu thread yang mengeksekusi kode synchronized pada objek tersebut. Monitor mencakup penguncian, antrian penantian, dan kumpulan thread yang menunggu pemberitahuan melalui wait/notify.

Apakah Lock lebih cepat dari synchronized?

Di versi Java modern (17+) synchronized tidak kalah dengan Lock dalam hal kinerja berkat optimalisasi JIT (biased locking, lock coarsening). Lock lebih dipilih bukan karena kecepatan, tetapi karena kemampuan tambahan: batas waktu, penantian yang dapat diinterupsi, dan beberapa Condition.

Bagaimana cara kerja synchronized dengan metode statis?

Metode statis synchronized menggunakan monitor objek Class dari kelas tersebut, bukan instance. Ini berarti sinkronisasi mencakup semua instance kelas. Metode synchronized non-statis dan statis menggunakan monitor yang berbeda dan tidak saling memblokir.

Ringkasan

  • Synchronized — mekanisme sinkronisasi Java bawaan berdasarkan monitor.
  • Monitor objek — struktur internal JVM yang memastikan saling eksklusi.
  • Metode wait/notify hanya digunakan di dalam blok atau metode synchronized.
  • Blok synchronized lebih diutamakan daripada metode karena granularitas sinkronisasi yang lebih halus.
  • Happens-before menjamin visibilitas perubahan antar thread saat sinkronisasi pada objek yang sama.
  • Deadlock — risiko utama dalam sinkronisasi bersarang dengan urutan monitor berbeda.
  • Alternatif — Lock, kelas atomik, dan coroutine dengan suspending Mutex.

Kami akan mengembangkan aplikasi seluler turnkey

IT Sectr membuat aplikasi iOS dan Android untuk startup dan bisnis sejak 2017. Kami akan memberi saran dan mengusulkan solusi terbaik.

Diskusikan proyek

Baca juga