33、volatile

在实际项目使用并不多,但是容易出错。很多人感觉和synchronized差不多,实际上完全不一样。我们看一下两者的区别:

volatile保证程序的可见性,这个和synchronize的区别就非常大,首先volatile他并不保证原子性。synchronized可以保证原子性,

什么叫原子性呢? 就是多个线程同时操作一个数据或则方法时,他们没有办法同时操作,只有一个操作完毕,另一个才能操作。

什么是可见性呢?线程在访问这样一个变量的时候,他都会去读取最新的值,即便被其他线程修改了。

volatile保证可见性,他的实现原理:内存直读,禁止指令重排序。

内存直读就是每次都从内存中读取,不会走任何的缓存。这样可以保证每次读到的都是新的。

因为变量发生变化的时候,就是内存对应某个地址的值发生变化,不管任何线程去操作,每次都从内存地址里面去读出来的数肯定是在这个时刻最新的值。

那什么情况下会发生读到老的数据呢

cpu有自己的缓存和寄存器,从内存中拿到数据,然后放到缓存或则寄存器里面处理,这样就有一个时间差。

比如我们有一个数据在没有读到cpu缓存之前就有其他线程来读取,那么他读取到的是什么呢?是缓存中老的值,还没有同步。

非volatile是从缓存里面读,读了再执行,可能被修改

volatile变量直接去内存里面找。保证每次都读最新的。

 

禁止重排序

首先我们看下什么是cpu指令的重排序,cpu允许将多条指令,不按照程序规定的顺序来执行。我们知道cpu执行会把多条指令进行一定的优化,把他拆成若干块,然后把各部分发给相应的电路单元来处理。A=B B=C c=A  A=B B=C  其实cpu只执行两句  A=b  b=c  其他的可能会被优化掉  

比如,我们new 一个对象,你认为先分配一个块内存地址,再去new 对象,有可能是找到一块缓存区,先构造了一个对象,然后在分配地址,然后在分配指向。和我们想的不一样。

禁止重排序就是,在读取地址内容的时候,在最后增加了一句,内存屏障,他告诉cpu,不允许把这后面内存排到他之前。保证了前面都是有序的。

synchronized 

既可以保证可见性,又能够保证原子性。

可见性体现在:通过synchronized或者Lock能保证同一时刻只有一个线程获取锁然后执行同步代码,并且在释放锁之前会将对变量的修改刷新到主存中。

原子性表现在:要么不执行,要么执行到底。

虽然效率比synchronized高,但是容易出粗,不好排查错误,但是不推荐使用。

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
这段代码定义了一些变量和函数,并实现了一个驱动直流电机的函数 motor()。 变量: - sp、si、sd 分别表示加速度 PID 控制器的参数,用于控制直流电机的加速度。 - dl 表示电机的死区,即在此区域内电机不会转动。 - count 是一个计数器变量。 - all 是一个有符号整型变量,用于计算某个值的总和。 - s 是一个长度为 2 的 unsigned char 类型数组,用于存储数据。 - data 是一个未指定类型的变量。 - mpuInterrupt 是一个 volatile bool 类型的变量,用于标识中断是否发生。 函数: - dmpDataReady() 函数用于设置中断标志位,表示 MPU6050 传感器中已经有新的数据可用。 - motor() 函数用于驱动直流电机。函数接收一个整型参数 v,表示电机的转速。函数体中,首先判断 v 的值是否大于死区,若大于则执行下列操作: - 将 v 加上 dl,表示加上电机的死区。 - 调用 digitalWrite() 函数将引脚 6、7、8、9 的电平分别设置为 HIGH、LOW、HIGH、LOW,用于控制电机的转向。 - 调用 analogWrite() 函数将引脚 10 和 11 的电压设置为 v,用于控制电机的转速。 其中,PID myPID(&Input,&Output, &setpoint,kp, ki, kd,DIRECT) 用于创建一个 PID 控制器对象,其中 Input、Output、setpoint 分别表示输入、输出和目标值,kp、ki、kd 分别表示比例、积分、微分系数,DIRECT 表示 PID 控制器的方向为正向。SPID(&Inputs,&Outputs,&Setpoints, sp, si, sd,DIRECT) 用于创建一个加速度 PID 控制器对象,其中 Inputs、Outputs、Setpoints 分别表示输入、输出和目标值,sp、si、sd 分别表示比例、积分、微分系数,DIRECT 表示 PID 控制器的方向为正向。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值