Kapan saya harus menggunakan StringBuilder atau StringBuffer?

13

Dalam aplikasi web produksi, sesama programmer saya menggunakan StringBuffer di mana-mana. Sekarang saya menangani pengembangan aplikasi dan koreksi. Setelah membaca StringBuilder dan StringBuffer, saya telah memutuskan untuk mengganti semua kode StringBuffer dengan StringBuilder karena kita tidak memerlukan keamanan thread pada data bean kita.

Sebagai contoh: (Di setiap data kacang saya bisa melihat penggunaan StringBuffer)

@Override
public String toString() {
    StringBuffer sb = new StringBuffer();// replace it from StringBuilder
    sb.append(" ABCD : ").append(abcd);
    sb.append(", EFGH : ").append(efgh);
    sb.append(", IJKL : ").append(ijkl);
}

Kami membuat data terpisah untuk setiap sesi / permintaan. Sesi digunakan oleh satu pengguna yang tidak dapat diakses oleh pengguna lain.

Haruskah saya mempertimbangkan poin lain sebelum bermigrasi?

Jika ada utas tunggal (tidak ada utas tunggu / tidak ada utas baru akan mencari kunci objek), itu berfungsi sama dengan baik StringBuffer atau StringBuilder. Saya tahu dalam kasus StringBuffer, dibutuhkan waktu untuk mengambil kunci objek tapi saya ingin tahu apakah ada perbedaan kinerja di antara mereka kecuali menahan / melepaskan kunci objek.

Satish Pandey
sumber
9
Jika Anda menggunakan sbsebagai variabel lokal seperti pada contoh Anda, maka keamanan utas sama sekali tidak masalah. Bahkan jika seribu utas secara bersamaan memasuki metode, masing-masing akan memiliki tumpukan panggilan sendiri dengan variabel lokalnya sendiri. The StringBuilders tidak akan pernah saling mengganggu.
fredoverflow
Saya selalu bertanya-tanya siapa yang ingin menyinkronkan dua utas di sepanjang sesuatu seperti antarmuka a StringBuffer. Saya belum pernah melihat kode seperti itu tapi saya hampir yakin itu desain yang buruk dari perspektif multithreading. Karena saya pikir menyinkronkan utas di sepanjang StringBufferantarmuka adalah ide yang buruk saya pikir kelas ini seharusnya tidak ada dan harus selalu digunakan StringBuilder. Seperti yang telah disebutkan orang lain, StringBufferada karena alasan historis.
pasztorpisti

Jawaban:

22

Satu-satunya perbedaan antara keduanya adalah sinkronisasi yang digunakan dalam StringBuffer. Overhead sinkronisasi tidak besar dalam skema besar hal-hal, tetapi signifikan relatif terhadap metode StringBuilder yang tidak memilikinya. JVM melakukan pekerjaan yang seharusnya tidak harus dilakukan - terutama dengan hanya satu utas, dll.

Jika kode Anda berfungsi dan orang-orang tidak mengeluh tentang kinerja, saya tidak akan mengkhawatirkannya. Anda tidak akan mendapatkan banyak bang untuk uang Anda. Namun, jika Anda menulis kode baru, atau memperbarui kode yang menggunakan StringBuffer, saya sarankan untuk mengonversinya dengan StringBuilder secara bersamaan.

Matthew Flynn
sumber
Saya akan menambahkan ini bahwa Anda perlu mengingat keamanan thread kedua. StringBuilder tidak aman untuk thread.
Martijn Verburg
2
@ MartijnVerburg Benar, meskipun ditunjukkan di stackoverflow.com/questions/6775016/stringbuffer-is-obsolete/... bahwa ada beberapa kasus penggunaan yang membutuhkan beberapa utas untuk menggunakan instance yang sama dari pembuat String.
Matthew Flynn
4
@ MartijnVerburg: harus juga diperhatikan: jika Anda benar - benar membutuhkan keamanan thread maka kemungkinannya juga StringBuffertidak cukup! Ini menjamin bahwa itu tidak mengerem, tetapi posisi di mana Anda menambahkan tidak dapat dengan mudah dikontrol jika beberapa thread mengaksesnya sekaligus, sehingga sinkronisasi eksternal lain akan diperlukan.
Joachim Sauer
8

StringBuilder ditambahkan pada suatu titik (Java 1.5) untuk menjadi StringBuffer yang lebih baik dan lebih cepat dan kompiler menggunakannya di bawah kap untuk mengimplementasikan +operator pada Strings.

Ini berarti bahwa dengan menggunakan StringBuilder Anda tidak dapat membuat kode Anda berjalan di JVM lebih tua daripada ketika kelas diperkenalkan. Ini akan menjadi masalah bagi kami, untuk sementara waktu. Jika Anda selalu menjalankan yang terbaru, Anda tidak perlu peduli.

Saya tidak akan melalui proses optimasi yang Anda lalui, meskipun karena alasan berikut.

  • Di luar loop ketat keuntungannya dapat diabaikan. Kecuali jika secara eksplisit muncul sebagai hotspot di profiler, saya tidak akan repot.
  • Mengubah kode dapat menyebabkan kesalahan, dan Anda harus menguji ulang aplikasi Anda secara menyeluruh. Itu mungkin jauh lebih mahal daripada hidup dengan kelas yang disinkronkan dalam pengaturan yang tidak disinkronkan.
Frank Shearar
sumber
Saya setuju dengan Anda .. masih tidak dapat memahami maksud AndaOutside tight loops the advantage is negligible...
Satish Pandey
Mekanisme yang hilang di StringBuilder sebagai lawan StringBuffer adalah kecepatan perdagangan untuk keamanan utas. Itu peningkatan kecepatan sangat kecil, sehingga hanya penting jika dilakukan suatu banyak kali - ini biasanya terjadi di lingkaran kecil yang dilakukan berkali-kali.