什么是多线程中的上下文切换?线程安全问题

多线程中的上下文切换

在上下文切换过程中, CPU 会停止处理当前运行的程序,并保存当前程序运行的具体位置以便之后继续运行。从这个角度来看,上下文切换有点像我们同时阅读几本书,在来回切换书本的同时我们需要记住每本书当前读到的页码。
在程序中,上下文切换过程中的 页码 信息是保存在进程控制块( PCB )中的。 PCB 还经常被称作“ 切换桢 switchframe )。 页码 信息会一直保存到 CPU 的内存中,直到他们被再次使用。
上下文切换是存储和恢复 CPU 状态的过程,它使得线程执行能够从中断点恢复执行。上下文切换是多任务操作系统和多线程环境的基本特征。

线程安全

简单来说,在多个线程访问某个方法或者对象的时候,不管通过任何的方式调用以及线程如何去交替执行。在程序中不做任何同步干预操作的情况下,这个方法或者对象的执行/修改都能按照预期的结果来反馈,那么这个类就是线程安全的。

线程安全问题

实际上,线程安全问题的具体表现体现在三个方面,原子性、有序性、可见性。

原子性

原子性呢,是指当一个线程执行一系列程序指令操作的时候,它应该是不可中断的,因为一旦出现中断,站在多线程的视角来看,这一系列的程序指令会出现前后执行结果不一致的问题。 这个和数据库里面的原子性是一样的,简单来说就是一段程序只能由一个线程完整的执行完成,而不能存在多个线程干扰。 CPU 的上下文切换,是导致原子性问题的核心,而 JVM 里面提供了 Synchronized 关键字来解决原子性问题。

可见性 

可见性,就是说在多线程环境下,由于读和写是发生在不同的线程里面,有可能出现某个线程对共享变量的修改,对其他线程不是实时可见的。 导致可见性问题的原因有很多,比如 CPU 的高速缓存、CPU 的指令重排序、编译器的 指令重排序。

有序性

有序性,指的是程序编写的指令顺序和最终 CPU 运行的指令顺序可能出现不一致的现象,这种现象也可以称为指令重排序,所以有序性也会导致可见性问题。可见性和有序性可以通过 JVM 里面提供了一个 Volatile 关键字来解决。

总结

在我看来,导致有序性、原子性、可见性问题的本质,是计算机工程师为了最大化提升CPU 利用率导致的。比如为了提升 CPU 利用率,设计了三级缓存、设计了 StoreBuffer、设计了缓存行这种预读机制、在操作系统里面,设计了线程模型、在编译器里面,设计了编译器的深度优化机制。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值