Di antara peralatan teks Java, StringBuffer adalah yang paling sering memunculkan pertanyaan: method-nya nyaris sama persis dengan StringBuilder, jadi untuk apa dua class terpisah? Jawabannya berakar pada sejarah dan kebutuhan keamanan thread. StringBuffer hadir sejak Java 1.0 tahun 1996 sebagai wadah teks yang bisa diubah, dan seluruh method publiknya ditandai synchronized agar aman dipakai beberapa thread sekaligus. Lima versi kemudian, Java 5 memperkenalkan StringBuilder — kembaran tanpa penguncian — setelah pengukuran performa menunjukkan penguncian tersebut membebani kasus paling umum: satu thread merangkai teks. Chapter ini membandingkan keduanya dan menentukan kapan masing-masing layak dipilih.
API Kembar dengan Jiwa Berbeda #
Mari kita jalankan operasi yang sama pada kedua class — append, insert, reverse — dan membandingkan hasilnya:
public class PenyanggaTeks {
public static void main(String[] args) {
StringBuffer penyangga = new StringBuffer("Halo");
penyangga.append(", dunia");
penyangga.insert(0, ">> ");
penyangga.reverse();
System.out.println("Isi : " + penyangga);
System.out.println("Panjang : " + penyangga.length());
StringBuilder pembangun = new StringBuilder("Halo");
pembangun.append(", dunia");
pembangun.insert(0, ">> ");
pembangun.reverse();
System.out.println("Builder : " + pembangun);
System.out.println("Sama? : " + penyangga.toString().equals(pembangun.toString()));
}
}Output yang Dihasilkan:
Isi : ainud ,olaH >>
Panjang : 14
Builder : ainud ,olaH >>
Sama? : trueBedah singkatnya: baris 3-7 memanipulasi StringBuffer dan baris 9-13 melakukan hal yang sama pada StringBuilder. Method append, insert, length, reverse, hingga toString tersedia di keduanya dengan tanda tangan yang sama, sehingga hasil akhirnya juga sama — teks ">> Halo, dunia" terbalik menjadi "ainud ,olaH >>". Perbedaan keduanya tidak terlihat dari output; perbedaannya ada di level bytecode, tempat setiap method StringBuffer membawa penanda synchronized.
Apa Arti synchronized di Sini #
Kata kunci synchronized pada method berarti: sebelum thread mana pun mengeksekusi method tersebut, thread harus mengunci objeknya lebih dulu, dan thread lain menunggu hingga kunci dilepas. Pada StringBuffer, penguncian itu terjadi di setiap panggilan append, insert, atau delete — sehingga dua thread yang bersamaan mengisi satu StringBuffer yang sama tidak akan saling menimpa larik internal. StringBuilder tidak mengunci apa pun: operasinya lebih cepat karena tanpa biaya koordinasi, tetapi pemakaian bersama antar thread bisa merusak isinya.
Risiko tanpa penguncian konkret begini: append tidak sekadar menulis — operasi tersebut membaca posisi akhir larik, menyalin karakter, lalu memperbarui posisi. Dua thread yang melakukan rangkaian langkah itu secara bersamaan bisa membaca posisi yang sama, menulis di tempat yang sama, dan hasil akhirnya kehilangan sebagian teks. Itulah kondisi balapan (race condition) yang dicegah synchronized.
| Aspek | StringBuffer | StringBuilder |
|---|---|---|
| Ada sejak | Java 1.0 (1996) | Java 5 (2004) |
| Method publik | synchronized | tanpa penguncian |
| Aman multi-thread | ya (per operasi) | tidak |
| Kecepatan satu thread | lebih lambat (biaya kunci) | lebih cepat |
| API method | nyaris identik | nyaris identik |
Kapan StringBuffer Masih Relevan #
Kehadiran StringBuffer terutama dijaga oleh kompatibilitas mundur — pustaka lama dan API warisan masih menerimanya, dan kode yang benar-benar membagikan wadah teks ke beberapa thread bisa memanfaatkannya sebagai opsi sederhana. Untuk kode baru pada umumnya: variabel StringBuilder selalu bersifat lokal dalam satu method (tidak pernah dibagikan), jadi penguncian StringBuffer hanya menjadi beban tanpa manfaat — gunakan StringBuilder. Bila kebutuhan konkurensinya lebih kompleks daripada satu wadah bersama, solusi yang lebih tepat biasanya bukan StringBuffer, melainkan desain yang tidak berbagi state sama sekali — misalnya tiap thread merangkai teksnya sendiri lalu hasilnya digabung di akhir.
Sejarah singkat ini menutup trilogi perakit teks: String yang beku, StringBuilder yang gesit, dan StringBuffer yang tertib di keramaian. Topik berikutnya melompat ke fitur sintaks modern untuk teks multi-baris: text blocks, cara menuliskan JSON dan SQL berbaris-baris tanpa tumpukan karakter escape.
Referensi #
Berkas Sumber
Berkas pendukung halaman ini dapat diunduh dan dijalankan langsung sesuai penjelasan di atas.
PenyanggaTeks.java
Unduh berkaspublic class PenyanggaTeks {
public static void main(String[] args) {
StringBuffer penyangga = new StringBuffer("Halo");
penyangga.append(", dunia");
penyangga.insert(0, ">> ");
penyangga.reverse();
System.out.println("Isi : " + penyangga);
System.out.println("Panjang : " + penyangga.length());
StringBuilder pembangun = new StringBuilder("Halo");
pembangun.append(", dunia");
pembangun.insert(0, ">> ");
pembangun.reverse();
System.out.println("Builder : " + pembangun);
System.out.println("Sama? : " + penyangga.toString().equals(pembangun.toString()));
}
}