เมื่อใดที่ฉันควรใช้ StringBuilder หรือ StringBuffer


13

ในเว็บแอปพลิเคชั่นการผลิตโปรแกรมเมอร์เพื่อนของฉันใช้ StringBuffer ทุกที่ ตอนนี้ฉันกำลังดูแลการพัฒนาแอพพลิเคชั่นและการแก้ไข หลังจากอ่านStringBuilderและStringBufferฉันได้ตัดสินใจเปลี่ยนรหัส StringBuffer ทั้งหมดด้วย StringBuilder เพราะเราไม่ต้องการความปลอดภัยของเธรดใน data beans ของเรา

ตัวอย่างเช่น: (ในแต่ละ data bean ฉันสามารถเห็นการใช้งานของ 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);
}

เราสร้าง data beans แยกต่างหากสำหรับแต่ละเซสชั่น / คำขอ เซสชันถูกใช้โดยผู้ใช้คนเดียวซึ่งไม่มีผู้ใช้รายอื่นสามารถเข้าถึงได้

ฉันควรพิจารณาประเด็นอื่นก่อนย้ายหรือไม่

หากมีเธรดเดี่ยว (ไม่มีเธรดที่รออยู่ / ไม่มีเธรดใหม่ที่กำลังมองหาการล็อกวัตถุ) มันจะทำงานอย่างเท่าเทียมกันกับ StringBuffer หรือ StringBuilder ฉันรู้ในกรณีของ StringBuffer มันต้องใช้เวลาในการล็อควัตถุ แต่ฉันต้องการทราบว่ามีความแตกต่างด้านประสิทธิภาพระหว่างพวกเขาหรือไม่ยกเว้นการพัก / ปล่อยล็อควัตถุ


9
หากคุณใช้sbเป็นตัวแปรเฉพาะที่ในตัวอย่างของคุณความปลอดภัยของเธรดไม่สำคัญเลย แม้ว่าหนึ่งพันเธรดจะป้อนวิธีการพร้อมกัน แต่แต่ละรายการจะมี call stack ของตนเองพร้อมกับตัวแปรโลคัล StringBuilders จะไม่รบกวนซึ่งกันและกัน
fredoverflow

I'we StringBufferเคยสงสัยที่ต้องการที่จะประสานสองหัวข้อพร้อมบางอย่างเช่นอินเตอร์เฟซของการเป็น ฉันไม่เคยเห็นรหัสเช่นนั้น แต่ฉันเกือบจะแน่ใจว่ามันเป็นการออกแบบที่ไม่ดีจากมุมมองแบบมัลติเธรด เพราะผมคิดว่าตรงกันด้ายพร้อมอินเตอร์เฟซที่เป็นความคิดที่ไม่ดีผมคิดว่าชั้นนี้ไม่ควรมีอยู่และควรใช้StringBuffer StringBuilderตามที่คนอื่นพูดถึงแล้วStringBufferมีอยู่ด้วยเหตุผลทางประวัติศาสตร์
pasztorpisti

คำตอบ:


22

ข้อแตกต่างระหว่างสองอย่างนี้คือการซิงโครไนซ์ที่ใช้ใน StringBuffer ค่าใช้จ่ายในการซิงโครไนซ์ไม่มากในรูปแบบที่ยิ่งใหญ่ของสิ่งต่าง ๆ แต่มีความสำคัญเมื่อเปรียบเทียบกับวิธีการ StringBuilder ที่ไม่มี JVM กำลังทำงานที่ไม่จำเป็นต้องทำอย่างอื่น - โดยเฉพาะกับเธรดเดียวเท่านั้นเป็นต้น

หากรหัสของคุณใช้งานได้และผู้คนไม่ได้บ่นเรื่องประสิทธิภาพฉันจะไม่กังวลกับมัน คุณจะไม่ได้รับผลกระทบมากสำหรับเจ้าชู้ของคุณ อย่างไรก็ตามหากคุณกำลังเขียนรหัสใหม่หรือกำลังอัปเดตรหัสที่ใช้ StringBuffer ฉันขอแนะนำให้แปลงเป็น StringBuilder ในเวลาเดียวกัน


ฉันจะเพิ่มสิ่งนี้ที่คุณต้องคำนึงถึงความปลอดภัยของการสืบทอดของทั้งสอง StringBuilder ไม่ปลอดภัยเธรด
Martijn Verburg

2
@MartijnVerburg จริง ๆ แล้วมันชี้ให้เห็นในstackoverflow.com/questions/6775016/stringbuffer-is-obsolete/…ว่ามีกรณีการใช้งานน้อยมากที่ต้องการหลายเธรดเพื่อใช้อินสแตนซ์เดียวกันของตัวสร้างสตริง
Matthew Flynn

4
@MartijnVerburg: มันควรจะสังเกต: ถ้าคุณต้องการความปลอดภัยของเธรดจริงๆแล้วโอกาสที่StringBufferไม่เพียงพอเช่นกัน! มันรับประกันว่ามันจะไม่เบรค แต่ตำแหน่งที่คุณผนวกไม่สามารถควบคุมได้อย่างง่ายดายถ้าหลายเธรดเข้าถึงได้ในครั้งเดียวดังนั้นจึงจำเป็นต้องซิงโครไนซ์ภายนอกอื่น
โจอาคิมซาวเออร์

8

StringBuilder ถูกเพิ่มที่จุด (Java 1.5) เพื่อให้เป็น StringBuffer ที่ดีขึ้นและเร็วขึ้นและคอมไพเลอร์ใช้มันภายใต้ประทุนเพื่อดำเนิน+การกับ Strings

ซึ่งหมายความว่าโดยใช้ StringBuilder คุณไม่สามารถทำให้โค้ดของคุณทำงานบน JVM ที่เก่ากว่าเมื่อมีการเปิดคลาส นี่จะเป็นปัญหาสำหรับเราสักพัก หากคุณใช้งานล่าสุดคุณไม่จำเป็นต้องสนใจ

ฉันจะไม่ทำตามกระบวนการปรับให้เหมาะสมที่คุณทำ แต่ด้วยเหตุผลดังต่อไปนี้

  • นอกห่วงแน่นประโยชน์ได้เล็กน้อย เว้นแต่จะปรากฏเป็นฮอทสปอตใน profiler อย่างชัดเจนฉันจะไม่รบกวน
  • การเปลี่ยนรหัสอาจทำให้เกิดข้อผิดพลาดและคุณต้องทดสอบแอปพลิเคชันของคุณใหม่อย่างละเอียด นั่นอาจแพงกว่าการใช้คลาสที่มีการซิงโครไนซ์ในการตั้งค่าที่ไม่ซิงโครไนซ์

ฉันเห็นด้วยกับคุณ .. ยังไม่สามารถเข้าใจประเด็นของคุณOutside tight loops the advantage is negligible...
Satish Pandey

กลไกที่หายไปใน StringBuilder ซึ่งตรงข้ามกับ StringBuffer คือความเร็วในการซื้อขายเพื่อความปลอดภัยของเธรด การปรับปรุงความเร็วนั้นมีขนาดเล็กมากดังนั้นจึงเป็นเรื่องสำคัญหากมีการทำหลายครั้ง - นี่เป็นกรณีปกติในการวนรอบเล็ก ๆ ที่ทำหลายครั้ง
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.