violate关键字使用场景

简介: 通过代码案例讲述了violate关键字的作用以及使用场景。

先看一段代码:

package com.fsun.research.thread.violate;

public class MainTest {
	private static boolean ready;
	private static class CounterThread implements Runnable{

		@Override
		public void run() {
			while(!ready){
				
			}
		}
		
	}
	public static void main(String[] args) {
		new Thread(new CounterThread()).start();
		System.out.println("主线程睡眠300毫秒");
		try {
			Thread.sleep(300);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		ready=true;
	}
}
 

上面的例子中run方法会陷入到死循环中,这是因为CounterThread线程在主线程改变ready值之前已经从主内存中读取了ready的值到自己的工作内存(主线程睡眠300毫秒就是为了保证这一点),由于在while循环中不停大量的循环读取,jvm为了提高读取效率,对于这种高并发读取的情况是从线程的工作内存来读取,即使当主线程睡眠醒来改变了ready的值并更新了主内存但却并没有什么用。


再看下面一个例子:


package com.fsun.research.thread.violate;

public class MainTest {
	private static boolean ready;
	private static class CounterThread implements Runnable{

		@Override
		public void run() {
			System.out.println("ready====="+ready);
			try {
				Thread.sleep(1000);  //睡眠1秒
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
			System.out.println("1秒后读取到ready的值"+ready);
		}
		
	}
	public static void main(String[] args) {
		new Thread(new CounterThread()).start();
		System.out.println("主线程睡眠300毫秒");
		try {
			Thread.sleep(300);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		ready=true;
	}
}

主线程睡眠300毫秒为了保证CounterThread在主线程更新ready之前从主内存中读取到ready的值。CounterThread在睡眠1秒之后又读取ready的值,此时读取到了主线程更新过后的值。为了使程序的执行流程可控加入了线程休眠,实际上在测试的过程中不加入线程休眠,只要线程不在短时间内频繁的读取ready的值都没有出现读取到的ready的值错误的情况。

 

可见在高并发的情况下,对于共享变量jvm并不能保证每个线程读取到的值都是一样的。为了解决这个问题,jvm引入了violate关键字,使用violate关键字来进行声明的变量,每次都会从主内存读取,jvm不会为每个工作线程进行缓存。

目录
相关文章
|
监控 前端开发 Java
事件驱动的奇迹:深入理解Netty中的EventLoop
事件驱动的奇迹:深入理解Netty中的EventLoop
890 0
|
Java 数据库连接 Maven
IDEA下Maven骨架(archetype)搭建
通过Maven生成骨架(通用项目目录结构)流程记录
1985 1
|
人工智能 自然语言处理 并行计算
MeteoRA:多任务AI框架革新!动态切换+MoE架构,推理效率提升200%
MeteoRA 是南京大学推出的多任务嵌入框架,基于 LoRA 和 MoE 架构,支持动态任务切换与高效推理。
704 3
|
存储 缓存 Java
volatile关键字最全原理剖析
【9月更文挑战第27天】`volatile` 是一个用于修饰变量的关键字,告知编译器被修饰的变量可能在程序控制流之外被改变。在多线程环境下,`volatile` 确保变量的值每次从内存中读取,保持最新状态,但不能解决所有同步问题。在硬件交互中,`volatile` 用于内存映射的 I/O 操作,确保读取最新值。不同编程语言如 C/C++ 和 Java 中的 `volatile` 用法略有差异,但都是处理易变变量的重要工具。
671 5
|
Linux 应用服务中间件 nginx
|
数据安全/隐私保护
网络文件夹目前是以其他用户名和密码进行映射的——映射盘更换登录用户名问题
网络文件夹目前是以其他用户名和密码进行映射的——映射盘更换登录用户名问题
5931 0
网络文件夹目前是以其他用户名和密码进行映射的——映射盘更换登录用户名问题
|
数据采集 安全 网络安全
代理IP纯净度如何测试?
代理IP的纯净度关乎网络隐私、稳定性和安全性。纯净IP能保护用户身份,提供稳定连接,降低被识别为恶意访问的风险,并确保数据安全。测试纯净度包括检查IP历史、黑名单状态、SSL支持、匿名度及网络性能。在网络安全至关重要的今天,纯净代理IP是重要保障。
|
安全 算法
HashMap和Hashtable 的区别
HashMap和Hashtable 的区别
392 0
|
Java API Spring
Spring Boot中如何处理异步任务
Spring Boot中如何处理异步任务
|
缓存 监控 网络协议
dpdk课程学习之练习笔记五(kni理解及测试)
dpdk课程学习之练习笔记五(kni理解及测试)
738 0

热门文章

最新文章