面试题答案
一键面试JVM内存模型角度
- 共享变量可见性:
StringBuffer
内部维护了一个字符数组用于存储字符串内容,这是共享变量。在多线程环境下,当一个线程调用append
方法修改这个字符数组时,由于StringBuffer
的方法使用了synchronized
关键字修饰,根据JVM内存模型的规则,线程在进入synchronized
块时会从主内存中重新读取共享变量的值,在退出synchronized
块时会将修改后的值刷新回主内存,确保其他线程能够看到最新的修改。 - 指令重排序:
synchronized
关键字可以防止指令重排序。在append
方法执行过程中,不会出现指令重排序导致其他线程看到不一致的中间状态。因为StringBuffer
的方法是同步的,在同步块内的操作是按照顺序执行的,从而保证了数据的一致性。
锁机制角度
- 对象锁:
StringBuffer
的append
方法被synchronized
关键字修饰,这意味着当一个线程调用append
方法时,它会获取StringBuffer
实例对象的锁。在同一时刻,只有获取到锁的线程才能执行append
方法,其他线程只能等待锁的释放。 - 锁的粒度:这里锁的粒度是针对
StringBuffer
实例对象。只要多个线程操作的是同一个StringBuffer
实例,就会通过竞争该实例的锁来保证线程安全。如果是不同的StringBuffer
实例,由于每个实例有自己独立的锁,不同实例上的append
操作不会相互影响,各自线程安全。 - 锁的获取与释放:当一个线程获取到
StringBuffer
实例的锁并执行append
方法时,在方法执行完毕(正常结束或者抛出异常)后,会自动释放锁,使得等待队列中的其他线程有机会获取锁并执行append
方法。