StringBuilder isn't thread safe, but as long as you use it from a single thread you don't have to worry about it. Even if you do access from two threads you can easily make it thread safe by enclosing the critical section with a synchronized block, e.g.
private StringBuilder sb = new StringBuilder();
void appendSomething(String v) {
synchronized (sb) {
sb.append("You entered ");
sb.append(v);
}
}
If the entire method is the critical section you can say synchronized on the method
synchronized void appendSomething(String v) {
sb.append("You entered ");
sb.append(v);
}
Note I explicitly wrote two append statements to demonstrate that just using thread safe StringBuffer wouldn't make code thread safe. If you ran two threads with a StringBuffer then each append might be synchronized but it would still be possible for race conditions to occur.
private StringBuffer sb = new StringBuffer();
void appendSomething(String v) {
sb.append("You entered ");
// Race condition!!!
sb.append(v);
}
So two threads writing "hello" and "world" might result in the output "You entered You entered helloworld" because each append is protected not the whole action.
Using synchronized classes are also less efficient. For example in the above example, both calls to append are synchronized so in addition to a race condition I have to lock the object twice compared to once with the non-synchronized class.