分配内存的时候为什么会线程不安全? 因为JVM堆内存是共享的 创建对象是会在多个线程中都会出现的操作 线程在new对象的时候,需要拿一块内存去存放,可以理解为需要从一个空闲内存列表中拿取空闲内存。 如果不做任何限制,那么多线程的场景下,极有可能出现多个线程分配到同一块内存的情况。 也就是所谓的线程不安全了
如何解决 解决线程不安全的思想大概可以归为两类
解决方法1-加锁: 一个很通用的思想就是,给线程不安全的操作加锁 同样适用于分配内存 如果我们给jvm堆中,分配内存这个操作加锁,所有线程需要new对象,需要内存去实例化的时候,都需要先获取这个"分配内存锁"。 很显然,是可以保证线程安全的,不会出现多个线程分配到同一块内存的情况 但是缺点也是明显的,因为分配内存这是一个高并发的操作,如果给这个操作加锁,那么会极大的影响效率。 解决方法2-线程隔离: 线程隔离的思想其实也有很多用处,比如编程时候常见的ThreadLocal 或者是JVM内存模型ThreadLocal 在jvm分配内存的时候也可以用到线程隔离的思想,就是TLAB(Thread Local Allocation Buffer) 简单来说,就是每个线程在创建的时候,会分配到一块属于自己的内存 内存大小由jvm当时运行情况计算决定 这块内存的特殊性就在于,jvm分配内存的时候会优先分配到自己的TLAB中,除此之外的操作都和堆中其他内存块没有区别 这个方式比加锁要高效很多。
|