面试题答案
一键面试可能出现的问题
- 数据不一致:多个线程同时对
StringBuilder
对象进行追加、插入等操作时,可能会导致最终结果与预期不符。例如,线程A和线程B同时向StringBuilder
追加字符,由于操作的交织,可能会出现字符顺序错乱的情况。 - 程序异常:在极端情况下,可能会导致程序抛出异常,例如
IndexOutOfBoundsException
等,因为不同线程对StringBuilder
内部状态(如索引、容量等)的修改可能相互干扰。
问题产生的原因
StringBuilder
是非线程安全的,其内部方法没有进行同步控制。当多个线程同时访问和修改StringBuilder
对象时,会出现竞态条件(Race Condition)。例如,一个线程在进行追加操作时,另一个线程可能同时修改了StringBuilder
的长度或内部数组,导致第一个线程的操作基于错误的状态进行,从而产生数据不一致或异常。
解决方案
- 使用
StringBuffer
:StringBuffer
是线程安全的,其方法都使用了synchronized
关键字进行同步。示例代码如下:
StringBuffer stringBuffer = new StringBuffer();
// 多线程环境下可安全使用stringBuffer的方法,如append等
- 使用
synchronized
关键字同步代码块:对涉及StringBuilder
操作的代码块进行同步。示例代码如下:
StringBuilder stringBuilder = new StringBuilder();
synchronized (stringBuilder) {
stringBuilder.append("some text");
}
- 使用
Lock
接口:通过ReentrantLock
等实现类来手动控制同步。示例代码如下:
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
StringBuilder stringBuilder = new StringBuilder();
Lock lock = new ReentrantLock();
lock.lock();
try {
stringBuilder.append("some text");
} finally {
lock.unlock();
}