面试题答案
一键面试选择StringBuffer而非StringBuilder的原因
- 线程安全:
StringBuffer
中的方法(如append
、insert
等)大多是同步的,这意味着在多线程环境下,当一个线程访问StringBuffer
的同步方法时,其他线程会被阻塞,直到该线程释放锁,从而保证了线程安全。例如:
StringBuffer sb = new StringBuffer();
synchronized(sb) {
sb.append("Hello");
}
- 而
StringBuilder
的方法是非同步的,在多线程环境下,如果多个线程同时对StringBuilder
进行操作,可能会导致数据不一致的问题。比如,线程A和线程B同时调用StringBuilder
的append
方法,可能会出现交错追加的情况,导致最终结果不符合预期。
- 性能:虽然
StringBuffer
由于同步机制会带来一定的性能开销,但在多线程且线程安全要求较高的场景下,这种开销是必要的,以确保数据的一致性。相比之下,StringBuilder
虽然性能更高(因为没有同步开销),但无法保证线程安全,在多线程场景下不适用。
选择String带来的问题
- 不可变性导致频繁创建对象:
String
是不可变的,每当对String
进行一次操作(如拼接、替换等),都会创建一个新的String
对象。例如:
String str = "Hello";
str = str + " World";
在上述代码中,str + " World"
操作会创建一个新的 String
对象,原来的 "Hello"
对象并不会改变。在多线程环境下,频繁的对象创建和销毁会增加垃圾回收的负担,降低系统性能。
2. 锁竞争:如果在多线程环境下使用 String
进行频繁操作,由于每次操作都创建新对象,可能会导致多个线程同时竞争这些新创建的对象,从而产生锁竞争问题,进一步影响性能。而且由于 String
不可变,对其操作时无法像 StringBuffer
那样通过同步方法来保证操作的原子性,可能会引发数据不一致的问题。