许久后的更新-------JAVA多线程编程-synchronized和volatile

最近忙于各种事情 停发了3个月吧 学到了不少的知识 今天总结下JAVA多线程的知识

绝对给你讲的明明白白滴
1.首先得了解并发和并行的概念

并发 :是指同一个时间段内多个任务同时在执行
并行:在单位时间内多个任务在执行
有人说并发和并行不是一样的吗? 解答:并发的一个时间段可以由多个单位时间累计而成,不一定是单位时间内多个任务在同时执行

在多线程程序中,会产生许多多线程问题,如:竞态条件,数据竞争等。这就需要在线程访问共享变量时进行适当的同步。

一个多线程竞态条件的问题:有一个计数器,多个线程可以对它进行递增操作,但递增操作由 获取-计算-保存三步骤,
假设:多线程1获取了计数器的值,正准备更新计算新值,线程2在它计算前先获取了该值,这就会导致俩次计算完的值是2,而正确的值为3,出现了多线程的问题。

下面讲解内存可见性问题(访问一级内存的问题):

先讲解内存模型:
多核CPU:每个核中含有一组寄存器,操作控制器,等。还有自身的一级缓存
有的里有含所有CPU共享的二级缓存
还有一个主内存

当一个线程操作共享变量时,它首先从主内存复制共享变量到自己的工作内存,然后对工作内存里的变量进行处理,处理完后讲变量值更新回主内存

这时问题来了 假设:(线程A和线程B不同CPU执行)线程A和线程B同时处理主内存中某个变量,当线程A获取了主内存中该变量并保存到二级缓存,再到一级缓存,假设更新的值为1(成功)。然后线程B进入修改该变量,从二级缓存中获取了该变量的值为1,并存到线程的一级缓存中,再将它更新回一级缓存,二级缓存,主内存,更新为2。但如果线程A再次进入获取该值,会获取线程A中的一级缓存,这是的线程A的一级缓存的值为1.这就出现了内存可见性的问题。

synchronized:是JAVA中的一种原子性内置锁。当线程进入synchronized代码块前会自动获取内部锁,这是后其他线程访问该同步代码块时会被阻塞挂起(访问不了其他代码,线程不能动的意思).拿到内部锁的线程会在正常退出或抛出异常或在同步块内使用wait等方法时释放该锁。

synchronized内存语义:是把在 synchronized中使用到的变量从线程中的工作内存(一级缓存)中清楚,这样在synchronized中使用该变量就不会从工作内存中获取,而是直接从主内存获取
退出synchronized块的内存语义是:把synchronized内对共享变量的修改刷新到主内存
volatile:保证了一个变量的更新对其他线程马上可见,当变量声明为volatile时,线程写入变量时不会把值缓存在寄存器或其他地方,而把值刷新回主内存。
注意:synchronized会造成内存的大开销。volatile无法保证原子性就是 获取-计算-保存,只保证内存的可见性。

累了累了 打了这么多字

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值