Java-多线程并发04并发基础知识

并发和并行:

并发是大时间段,并行是小时间段。

如果多个线程一起访问共享资源,至少一个线程进行修改操作,会出现线程安全问题。

 

JAVA内存模型知识:

当一个线程操作共享变量时,它首先从主内存复制共享变量到自己的工作内存中,然后在工作内存对变量进行修改,处理完后将变量的值更新到主内存中去。

 

 

例如这种CPU架构

双核CPU,每个核都有自己的控制器,运算器,Cache(一级缓存)

还有一个共享的二级缓存。

在线程修改数据,会先往cache中进行查找是否有相同的数据,如果有的话就直接用,两次都没有命中就写入内存,然后更新到缓存中去。

 

 

 

 

共享变量内存不可见问题:

线程A写数据到主内存,加载到缓存中。线程B修改缓存中的A修改过的值。并同步更新到缓存和内存中。当线程A再次修改值的时候,看不到线程B修改过的值。

 

Synchronized:
JAVA内置锁。解决内存不可见的问题。但是会引起上下文切换的开销。

内存语义:

进入Synchronized:清空锁块内本地内存中将要用到的变量,需要用的时候去主存中加载

退出Synchronized:把块内对本地变量的修改的共享变量刷新到内存中

 

Volatile:
非阻塞,不会引起上下文切换的开销。弱同步,该关键字确保对一个变量的更新对其他线程立马可见。

对变量的声明时使用。

内存语义:

获取:退出Synchronzed

写入:进入Synchronized

 

伪共享:

多线程访问同一个cache行中的多个变量时候会出现效率的不理想状态。因为会出现线程间对cache行资源的争夺使用。

但是如果是单线程访问,由于访问时会因为局部性原理加载附近内存地址的元素。对效率的提升大有好处。

避免的方法:

字节填充法。通过字节填充让每个cache行只存在一个变量

注释@sun.misc.Contended

posted @ 2021-04-01 21:12  NobodyHero  阅读(65)  评论(0编辑  收藏  举报