Many people have mentioned that the difference between StringBuffer and StringBuilder in Java. StringBuffer contains synchronized methods. And people say things like "if a buffer is used by many threads, use StringBuffer." But is the use of StringBuffer really going to guarantee "thread-safety"?
-
Asking and answering.Wats this ?? – Kick Mar 14 '14 at 17:46
-
1@Youngistan Yes, that is allowed. – rgettman Mar 14 '14 at 17:49
-
1@Youngistan Hello.. stackoverflow gives me an option to share knowledge, Q&A style. – Kevin Lee Mar 14 '14 at 17:50
-
1Ohkk i was not aware about this. – Kick Mar 14 '14 at 17:50
-
I've flagged this for moderator attention. The question was asked merely to showcase the answer on a blog. It is better suited to a blog post. It also duplicates other threads. This answer could be posted to one of the other threads and nothing would be lost. – mttdbrd Mar 14 '14 at 17:51
-
@mttdbrd I don't understand. I am a student learning about concurrency and I have zero affiliations with that blog lol. I wrote the program on top on my own as well. – Kevin Lee Mar 14 '14 at 17:53
-
StackOverflow is for you to ask questions. You are allowed to answer your question. I just think this question is a) a duplicate of other questions, and b) was designed just to showcase your answer. Basically, you could just post the answer below on an already existing thread, but it seems you wanted it to receive more attention so you asked a new question. You don't have a legitimate problem you're trying to solve. You may be excited about your answer and want to share it, but I think it is contrary to the goals of SO. That's my opinion. I'll leave it to moderators to decide. – mttdbrd Mar 14 '14 at 18:01
-
Since I answered this as Q&A style, it may have come across as if I am asking this question so that I can showcase my answer, and if you look down upon that, you are missing out the learning value here. I do take pride in whatever I do and I'm sure great profs do the same by presenting their best work. And the other reason why I asked this as a separate question was not just to talk about StringBuffer, but to actually highlight that any so-called "thread-safe" libraries do not guarantee concurrency and we should be mindful of assumptions. I felt that was impt enough to warrant a new post. – Kevin Lee Mar 14 '14 at 18:19
1 Answers
Well, I think it is important to highlight some actual uses of StringBuffer. To that end, I have designed a simple program to illustrate how StringBuffer can be superior to StringBuilder in achieving thread-safety.
/**
* Run this program a couple of times. We see that the StringBuilder does not
* give us reliable results because its methods are not thread-safe as compared
* to StringBuffer.
*
* For example, the single append in StringBuffer is thread-safe, i.e.
* only one thread can call append() at any time and would finish writing
* back to memory one at a time. In contrast, the append() in the StringBuilder
* class can be called concurrently by many threads, so the final size of the
* StringBuilder is sometimes less than expected.
*
*/
public class StringBufferVSStringBuilder {
public static void main(String[] args) throws InterruptedException {
int n = 10;
//*************************String Builder Test*******************************//
StringBuilder sb = new StringBuilder();
StringBuilderTest[] builderThreads = new StringBuilderTest[n];
for (int i = 0; i < n; i++) {
builderThreads[i] = new StringBuilderTest(sb);
}
for (int i = 0; i < n; i++) {
builderThreads[i].start();
}
for (int i = 0; i < n; i++) {
builderThreads[i].join();
}
System.out.println("StringBuilderTest: Expected result is 1000; got " + sb.length());
//*************************String Buffer Test*******************************//
StringBuffer sb2 = new StringBuffer();
StringBufferTest[] bufferThreads = new StringBufferTest[n];
for (int i = 0; i < n; i++) {
bufferThreads[i] = new StringBufferTest(sb2);
}
for (int i = 0; i < n; i++) {
bufferThreads[i].start();
}
for (int i = 0; i < n; i++) {
bufferThreads[i].join();
}
System.out.println("StringBufferTest: Expected result is 1000; got " + sb2.length());
}
}
// Every run would attempt to append 100 "A"s to the StringBuilder.
class StringBuilderTest extends Thread {
StringBuilder sb;
public StringBuilderTest (StringBuilder sb) {
this.sb = sb;
}
@Override
public void run() {
for (int i = 0; i < 100; i++) {
sb.append("A");
}
}
}
//Every run would attempt to append 100 "A"s to the StringBuffer.
class StringBufferTest extends Thread {
StringBuffer sb2;
public StringBufferTest (StringBuffer sb2) {
this.sb2 = sb2;
}
@Override
public void run() {
for (int i = 0; i < 100; i++) {
sb2.append("A");
}
}
}
However, like many others have pointed out also, StringBuffer is not a miracle cure for designing thread-safe applications. To go even further, I would say that the tools and libraries for concurrency (e.g. Vector) should be well-understood and appropriately implemented, and we should not make easy assumptions about using "thread-safe" libraries.
http://jeremymanson.blogspot.sg/2008/08/dont-use-stringbuffer.html
Jeremy's example illustrates the point, and I quote:
Thread 1:
sb.append("a");
Thread 2:
sb.append("b");
Thread 3:
join 1,2
print(sb.toString());
"Sure, it is "thread-safe", in the sense that there are no data races (which are basically concurrent accesses without adequate synchronization). But you have no idea what thread 3 will print: "ab" or "ba". I would have to introduce more synchronization to make this produce a sensible result. The locks that come with the StringBuffer haven't helped anything."
I hope this is insightful for you!

- 2,307
- 26
- 31