Di Java, apabila bekerja dengan rentetan bolehubah (rentetan yang boleh diubah suai), anda mungkin perlu memilih antara StringBuilder dan StringBuffer. Walaupun kedua-duanya adalah kelas boleh ubah yang membenarkan pengubahsuaian nilainya, ia berbeza dengan ketara dari segi keselamatan benang, prestasi dan aplikasi. Di sini, kami akan membandingkan ciri-ciri mereka dan menyediakan contoh kod untuk menggambarkan masa untuk menggunakan setiap satu.
Feature | StringBuilder | StringBuffer |
---|---|---|
Mutability | Mutable | Mutable |
Stored in | Heap (does not use String Pool) | Heap (does not use String Pool) |
Thread Safety | Not thread-safe | Thread-safe |
Synchronization | Not synchronized | Synchronized |
Performance | Faster due to lack of synchronization | Slower due to synchronization overhead |
Use Case | Single-threaded scenarios | Multi-threaded scenarios where thread-safety is required |
Mari teroka setiap kelas dengan lebih terperinci.
StringBuilder ialah kelas boleh berubah, bermakna ia membenarkan pengubahsuaian pada kandungannya.
Ia benang-tidak selamat, jadi ia sesuai untuk senario benang tunggal.
Tidak disegerakkan: StringBuilder lebih pantas daripada StringBuffer kerana ketiadaan overhed penyegerakan.
Penghadan berbilang benang: Menggunakan StringBuilder dalam persekitaran berbilang benang tanpa langkah keselamatan tambahan boleh membawa kepada keadaan perlumbaan dan isu konkurensi yang lain.
Dalam contoh ini, kami menggunakan dua urutan untuk menambahkan aksara pada tika StringBuilder. Walau bagaimanapun, disebabkan kekurangan penyegerakan, kami menghadapi keadaan perlumbaan:
public class StringBuilderBasics { public void threadUnsafe() { // Common resource being shared StringBuilder builder = new StringBuilder(); // Thread appending "A" 1000 times Thread t1 = new Thread(() -> { for (int i = 0; i < 1000; i++) { builder.append("A"); } }); // Thread appending "B" 1000 times Thread t2 = new Thread(() -> { for (int i = 0; i < 1000; i++) { builder.append("B"); } }); t1.start(); t2.start(); try { t1.join(); t2.join(); } catch (InterruptedException e) { e.printStackTrace(); } // Result: 1840 (unpredictable) System.out.println("Length: " + builder.toString().length()); } public static void main(String[] args) { new StringBuilderBasics().threadUnsafe(); } }
Penjelasan:
Disebabkan oleh ketidakselamatan benang, panjang akhir keluaran StringBuilder tidak dapat diramalkan (mis., 1840 bukannya 2000).
Ini berlaku kerana kedua-dua urutan cuba menambahkan aksara secara serentak, yang membawa kepada tulis ganti atau operasi digugurkan.
Takeaway: Gunakan StringBuilder hanya dalam persekitaran satu benang atau apabila keselamatan benang dikendalikan secara luaran.
StringBuffer adalah boleh berubah, membenarkan pengubahsuaian pada kandungannya.
Ia disegerakkan, yang menjadikannya selamat untuk benang.
Sesuai untuk persekitaran berbilang benang yang memerlukan keselamatan benang.
Kos prestasi: Penyegerakan memperkenalkan overhed, jadi StringBuffer adalah lebih perlahan daripada StringBuilder.
Berikut ialah contoh yang sama seperti di atas, tetapi kali ini menggunakan StringBuffer:
public class StringBufferBasics { public void threadSafe() { // Common resource being shared StringBuffer buffer = new StringBuffer(); // Thread appending "A" 1000 times Thread t1 = new Thread(() -> { for (int i = 0; i < 1000; i++) { buffer.append("A"); } }); // Thread appending "B" 1000 times Thread t2 = new Thread(() -> { for (int i = 0; i < 1000; i++) { buffer.append("B"); } }); t1.start(); t2.start(); try { t1.join(); t2.join(); } catch (InterruptedException e) { e.printStackTrace(); } // Result: 2000 System.out.println("Length: " + buffer.toString().length()); } public static void main(String[] args) { new StringBufferBasics().threadSafe(); } }
Penjelasan:
StringBuffer memastikan kedua-dua utas disambung dengan selamat, mencapai jangkaan panjang 2000.
Walaupun rentetan akhir selamat untuk benang, output mungkin berjalin (cth., “AAABBB...” dicampur bersama) kerana susunan pelaksanaan benang adalah bukan deterministik.
Takeaway: Gunakan StringBuffer untuk aplikasi berbilang benang di mana ketekalan data adalah penting dan penyegerakan diperlukan.
Untuk memutuskan antara StringBuilder dan StringBuffer, pertimbangkan perkara berikut:
Gunakan StringBuilder dalam senario benang tunggal di mana prestasi adalah kritikal dan keselamatan benang tidak menjadi kebimbangan.
Gunakan StringBuffer dalam senario berbilang benang di mana anda memerlukan operasi rentetan boleh ubah dan memerlukan keselamatan benang untuk mengelakkan keadaan perlumbaan.
Perbandingan ini seharusnya membantu anda membuat pilihan termaklum antara StringBuilder dan StringBuffer. Memahami pertukaran dalam kebolehubahan, prestasi dan keselamatan benang boleh membawa kepada membuat keputusan yang lebih baik apabila bekerja dengan rentetan dalam Java.
Selamat Pengekodan!
Atas ialah kandungan terperinci StringBuilder vs StringBuffer dalam Java. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!