头歌实践教学平台:Java高级特性-多线程基础(3)线程同步(四上)

发布时间:2026/9/16 9:15:07
头歌实践教学平台:Java高级特性-多线程基础(3)线程同步(四上) 第4关使用volatile实现变量的可见性任务描述本关任务使用volatile关键字与同步实现右侧程序输出10000。相关知识在并发编程中volatile关键字扮演着非常重要的作用接下来我们直接进入主题。什么是 volatile 关键字volatile是干啥用的有什么含义和特点呢当一个共享变量被volatile修饰时它就具备了“可见性”即这个变量被一个线程修改时这个改变会立即被其他线程知道。当一个共享变量被volatile修饰时会禁止“指令重排序”。先来看个例子//线程1boolean stop false;while(!stop){doSomething();}//线程2stop true;因为线程是不直接提供停止的方法的所以我们很多时候想要中断线程一般都会采用上述代码。不过这段代码是存在问题的当线程2执行时这段代码能保证一定能中断线程1吗在大多数情况下是可以的不过也有可能不能中断线程1。为何有可能导致无法中断线程呢每个线程在运行过程中都有自己的工作内存那么线程1在运行的时候会将stop变量的值拷贝一份放在自己的工作内存当中。那么当线程2更改了stop变量的值之后但是还没来得及写入主存当中线程2转去做其他事情了那么线程1由于不知道线程2对stop变量的更改因此还会一直循环下去。如何避免这种情况呢很简单给stop变量加上volatile关键字就可以了。volatile关键字会产生什么效果呢使用volatile关键字会强制将变量的修改的值立即写至主内存使用volatile关键字当线程2对变量stop修改时会强制将所有用到stop变量的线程对应的缓存中stop的缓存行置为无效。由于线程1的stop缓存行无效所以在运行时线程1会读取主存中stop变量的值。所以到最后线程1读取到的就是stop最新的值。volatile可以保证原子性吗在之前我们了解到了线程的三大特性原子性可见性有序性。前面的例子我们知道了volatile可以保证共享变量的可见性但是volatile可以保证原子性吗我们来看看public class Test {public volatile int inc 0;public void increase() {inc;}public static void main(String[] args) {final Test test new Test();for(int i0;i10;i){new Thread(){public void run() {for(int j0;j1000;j)test.increase();};}.start();}while(Thread.activeCount()1) //保证前面的线程都执行完Thread.yield();System.out.println(test.inc);}}来想一想这段程序的输出结果然后copy到本地运行看一看效果。可能我们想的结果应该是10000不过最终运行的结果往往达不到10000可能我们会有疑问不对啊上面是对变量inc进行自增操作由于volatile保证了可见性那么在每个线程中对inc自增完之后在其他线程中都能看到修改后的值啊所以有10个线程分别进行了1000次操作那么最终inc的值应该是1000*1010000。前面我们讲到volatile是可以保证可见性的不过上述程序的错误在于volatile没法保证程序的原子性。有任何问题都可以随时关注私信

关于本文作者

来自尧图内容编辑团队

尧图内容编辑团队 内容团队

尧图内容编辑团队

本文由尧图网络内容编辑团队执笔。团队由资深项目经理、前端工程师与设计师组成,所有内容均来自亲手交付的真实项目,先讲清问题、再给出可落地的解法。尧图深耕北京网站建设十年,服务过京华建材集团、智造科技等各行业客户,把一线经验沉淀为可复用的行业观察。

  • 十年建站经验,覆盖建材、制造、服务、文创等
  • 项目经理把关选题与事实准确性
  • 工程师与设计师联合撰写专业细节
  • 统一编辑规范,保证文风与排版一致
  • 每月复盘转化数据,迭代选题方向

延伸阅读

相关资讯与近期热门内容

深度阅读推荐

建站决策前值得细读的三篇

网站改版的5个关键决策
2024-08-12

网站改版的5个关键决策

什么时候该改版、改到什么程度、如何避免流量掉光,京华建材集团改版复盘给出答案。

获取专属建站方案

看完文章,把您的行业与预算告诉我们,免费获取一份量身定制的官网建设方案与报价。

立即免费咨询