加入收藏 | 设为首页 | 会员中心 | 我要投稿 惠州站长网 (https://www.0752zz.com.cn/)- 办公协同、云通信、物联设备、操作系统、高性能计算!
当前位置: 首页 > 业界 > 正文

不惜一切代价避免的13种情况

发布时间:2021-02-01 10:12:51 所属栏目:业界 来源:互联网
导读:10.4 Synchronized 无法禁止指令重排,却能保证有序性 指令重排是程序运行时 解释器 跟 CPU 自带的加速手段,可能导致语句执行顺序跟预想不一样情况,但是无论如何重排 也必须遵循 as-if-serial。 避免重排的最简单方法就是禁止处理器优化跟指令重排,比如vo

10.4 Synchronized 无法禁止指令重排,却能保证有序性

指令重排是程序运行时 解释器 跟 CPU 自带的加速手段,可能导致语句执行顺序跟预想不一样情况,但是无论如何重排 也必须遵循 as-if-serial。

避免重排的最简单方法就是禁止处理器优化跟指令重排,比如volatile中用内存屏障实现,syn是关键字级别的排他且可重入锁,当某个线程执行到一段被syn修饰的代码之前,会先进行加锁,执行完之后再进行解锁。

当某段代码被syn加锁后跟解锁前,其他线程是无法再次获得锁的,只有这条加锁线程可以重复获得该锁。所以代码在执行的时候是单线程执行的,这就满足了as-if-serial语义,正是因为有了as-if-serial语义保证,单线程的有序性就天然存在了。

10.5 wait 虚假唤醒

虚假唤醒定义:

当一个条件满足时,很多线程都被唤醒了,但只有其中部分是有用的唤醒,其它的唤醒是不对的,

比如说买卖货物,如果商品本来没有货物,所有消费者线程都在wait状态卡顿呢。这时突然生产者进了一件商品,唤醒了所有挂起的消费者。可能导致所有的消费者都继续执行wait下面的代码,出现错误调用。

虚假唤醒原因:

因为 if 只会执行一次,执行完会接着向下执行 if 下面的。而 while 不会,直到条件满足才会向下执行 while下面的。

虚假唤醒 解决办法:

在调用 wait 的时候要用 while 不能用 if。

10.6 notify()底层

1.为何wait跟notify必须要加synchronized锁

synchronized 代码块通过 javap 生成的字节码中包含monitorenter 和 monitorexit 指令线程,执行 monitorenter 指令可以获取对象的 monitor,而wait 方法通过调用 native 方法 wait(0) 实现,该注释说:The current thread must own this object's monitor。

2.notify 执行后立马唤醒线程吗?

notify/notifyAll 调用时并不会真正释放对象锁,只是把等待中的线程唤醒然后放入到对象的锁池中,但是锁池中的所有线程都不会立马运行,只有拥有锁的线程运行完代码块释放锁,别的线程拿到锁才可以运行。
 

我们看到全局变量global_num前加了关键词__thread修饰,这时,func代码就是又是线程安全的了。为什么呢?其实在上一篇文章中我们讲过,被__thread关键词修饰过的变量放在了线程私有存储中,Thread Local Storage,什么意思呢?意思是说这个变量是线程私有的全局变量:

  • global_num是全局变量
  • global_num是线程私有的

(编辑:惠州站长网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

推荐文章
    热点阅读