1. 为什么要进行多线程并发编程
多核CPU的到来打破了单核CPU对多线程效能的限制。多个CPU意味着每个线程可以使用自己的CPU运行,这减少了线程上下文的切换开销,但随着对应用系统性能和吞吐量的要求提高,出现了处理海量数据和请求的要求,这些都对高并发编程有着迫切的需求。
2. Java 的线程安全问题
谈到线程安全问题,我们先说说什么是共享资源。所谓的 共享资源,就是说该资源被多个线程持有或者说多个线程都可以访问该资源。
线程安全问题 是指当多个线程同时读写一个共享资源并且没有任何同步措施时,导致出现脏数据或者其他不可预见的结果的问题。
3. 为何会出现伪共享
什么是伪共享?
当多个线程同时修改一个缓存行里面的多个变量时,由于同时只能有一个线程操作缓存行,所以相比将每个变量放到缓存行,性能会有所下降,这就是伪共享。
伪共享的产生是因为多个变量被放入一个缓存行中,并且多个线程同时去写入缓存行中不同的变量。
那么为什么多个变量会被放入一个缓存行呢?
其实是因为缓存与内存交换数据的最小单位就是缓存行,当CPU要访问的变量没有在缓存中找到时,根据程序运行的局部性原理,会把该变量所在内存中大小为缓存行的内存放入到缓存行。
4. 如何避免伪共享
在JDK 1.8 之前 都是通过 字节填充的方式来避免伪共享的问题的,也就是创建一个变量时使用填充字段填充该变量所在的缓存行,这样就避免了将多个变量存放在同一个缓存行中。
JDK 1.8中提供了一个sun.misc.Contended 注解,用来解决伪共享问题。