当前位置: 首页 > news >正文

本地缓存:多线程问题。volatile

“你好,三妹!你还记得艾莉跟你讲过多个线程尝试同时访问共享资源时出现的问题,是吗?”

“是的。”

“关键是,这还不是全部。还有另外一个小问题。”

如你所知,计算机装有存储数据和命令(代码)的内存,以及执行这些命令和处理数据的处理器。处理器从内存中读取数据,进行更改,然后将其写回到内存中。为了加快计算速度,处理器有其自己的内置“快速”内存:缓存。

通过将最常用的变量和内存区域复制到缓存中,处理器可以更快地运行。接下来,它将在此快速内存中进行所有更改。然后将数据复制回“慢速”内存。在此期间,慢速内存包含旧的(未更改的!)变量。

这就是问题所在。一个线程更改变量,如上例中的 isCancel 或 isInterrupted,由于这是在快速内存中发生的,所以第二个线程“看不到这一更改”。这是因为线程无法访问彼此的缓存。(处理器通常包含几个独立的内核,线程可以在物理上不同的内核上运行。)

​编辑

我们来回想一下昨天的示例:

代码说明
class Clock implements Runnable {
private boolean isCancel = false;public void cancel()
{
this.isCancel = true;
}public void run()
{
while (!this.isCancel)
{
Thread.sleep(1000);
System.out.println("Tick");
}
}
}
线程“不知道”存在其他线程。

在 run 方法中,首次使用 isCancel 变量时将其放入子线程的缓存中。此操作等效于以下代码:

public void run()
{
boolean isCancelCached = this.isCancel;
while (!isCancelCached)
{
Thread.sleep(1000);
System.out.println("Tick");
}
}

从另一个线程中调用 cancel 方法将更改常规(慢速)内存中的isCancel 值,而不更改其他线程缓存中的值。

public static void main(String[] args)
{
Clock clock = new Clock();
Thread clockThread = new Thread(clock);
clockThread.start();Thread.sleep(10000);
clock.cancel();
}

“哇!他们是否也为此提出了一个完美的解决方法,就像 synchronized 一样?”

“你不会相信的!”

首先想到的是禁用缓存,但这使程序的运行速度慢了好几倍。然后出现了另一种解决方法。

创建了关键字 volatile。我们将此关键字放在变量声明之前,以指示不得将其值放入缓存中。更准确地说,并不是不能将该关键字放入缓存中,而是必须始终在常规(慢速)内存中读取和写入它。

通过以下方式修复我们的解决方法,可以使一切正常运行:

代码说明
class Clock implements Runnable
{
private volatile boolean isCancel = false;public void cancel()
{
this.isCancel = true;
}public void run()
{
while (!this.isCancel)
{
Thread.sleep(1000);
System.out.println("Tick");
}
}
}
volatile 修饰符使得始终在所有线程共享的常规内存中读取和写入变量。
public static void main(String[] args)
{
Clock clock = new Clock();
Thread clockThread = new Thread(clock);
clockThread.start();Thread.sleep(10000);
clock.cancel();
}

“完了?”

“就是这样。简单而美妙。”

http://www.dtcms.com/a/602338.html

相关文章:

  • 龙岗中心城有学网站建设晋城商城网站开发设计
  • 工业总线协议(Modbus RTU/TCP、PROFINET、EtherCAT)的帧结构、通信速率与实时性对比
  • 平谷青岛网站建设办公空间设计定位
  • 如何建设网站兴田德润可信赖自我介绍ppt配图
  • Oracle ADG 配置闪回导致报表查询延时!
  • 网站建设 好的公司吴江建设工程招标中心网站
  • 2025年安徽省科技创新战略与软科学研究专项重大项目申报条件要求流程
  • asp网站建设流程旅店网站建设规划书
  • uniapp 鸿蒙元服务 真机调试流程指南
  • 网站建设内存seo诊断工具网站
  • NeurIPS 2025 中科大等提出PIR:实例感知后处理修正框架,显著提升时序预测可靠性!
  • HaluMem:揭示当前AI记忆系统的系统性缺陷,系统失效率超50%
  • 异世界冒险:网络迷宫与生成树封印术
  • 怎样在网上做网站教程网站建设
  • JAVA后端面试笔记(三)
  • 【剑斩OFFER】算法的暴力美学——寻找峰值
  • 【DeepSeek实战】高质量提示词的六种类型
  • 从零开始学习PX4源码30(定高(ALTITUDE)模式)
  • 中国建设银行对公网站中国500强企业排名
  • 做网站的为什么不给域名和密码个人网页制作与网站建设
  • GIT基础使用教程
  • 想建设个人网站去那里建设宁德做网站的公司
  • wordpress网站seo专业展馆展厅设计
  • LangGraph智能知识库系统架构设计方案 - 多agent架构
  • 在线C语言编译 | 提供便捷高效的在线编程环境
  • 二级网站建设费用网站有备案号吗
  • 搭建Golang gRPC环境:protoc、protoc-gen-go 和 protoc-gen-go-grpc 工具安装教程
  • flutter项目老是卡在Running Gradle task ‘assembleRelease‘......
  • 东莞清溪镇做网站公司对网站有效的优化软件
  • Python的asyncio核心组件