violate java_violate关键字使用场景

本文通过示例分析了在高并发环境下,未使用volatile关键字时,线程可能读取到不同步的共享变量值,导致死循环或数据不一致。通过引入volatile,确保每次读取共享变量都直接从主内存获取,避免工作内存带来的数据延迟问题,从而保证多线程间的数据同步。
摘要由CSDN通过智能技术生成

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不会为每个工作线程进行缓存。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值