文档章节

violate关键字使用场景

CatCloud
 CatCloud
发布于 2015/11/21 22:49
字数 531
阅读 42
收藏 0
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不会为每个工作线程进行缓存。

 

© 著作权归作者所有

共有 人打赏支持
CatCloud
粉丝 0
博文 18
码字总数 51128
作品 0
南京
高级程序员
私信 提问
Java多线程Violate(可见性)Atomic(原子性)

violate保证了可见性但是不能保证原子性的情况; 解决了vialate关键字不能保证原子性(线程安全) 要求,一个线程去将count+1000的操作,输出1000,200010000 使用vialate打印出来的很明显不符...

码家EDU
2017/10/26
0
0
设计模式之禅之单例模式!

单例模式:创建全局的唯一一个实例! 1、普通单例 public class Singleton{ private Singleton single = null; private Singleton(){ } public Singleton getSingleton(){ if(null ==single ......

redis缓存
2018/03/06
0
0
我要做 Android 之单例模式

Q:实现单例模式有几种方法?懒汉式中双层锁的目的是什么?两次判空的目的又是什么? 懒汉式(线程不安全) 单例模式最后的目的无非就是获取当前存在的实例对象,如果没有实例对象就实例化一...

迎着风
2018/09/12
0
0
[译文]深入理解JavaScript的this关键字(一)

原文:Understand JavaScript’s “this” With Clarity, and Master It 翻译成两篇文章: [译文]深入理解JavaScript的this关键字(一) [译文]深入理解JavaScript的this关键字(二) 1 前言...

huangpin815
2017/09/06
0
0
京东java研发实习初试(电面)

static关键字,final关键字 栈和队列的区别 找单链表的倒数第K个节点 二叉树的先序遍历(递归和非递归),属于深度优先还是广度优先 线程同步实现,synchronized关键字使用方式及区别 tcp与u...

程序媛媛51
2017/04/16
0
0

没有更多内容

加载失败,请刷新页面

加载更多

容器服务

简介 容器服务提供高性能可伸缩的容器应用管理服务,支持用 Docker 和 Kubernetes 进行容器化应用的生命周期管理,提供多种应用发布方式和持续交付能力并支持微服务架构。 产品架构 容器服务...

狼王黄师傅
昨天
2
0
高性能应用缓存设计方案

为什么 不管是刻意或者偶尔看其他大神或者大师在讨论高性能架构时,自己都是认真的去看缓存是怎么用呢?认认真真的看完发现缓存这一块他们说的都是一个WebApp或者服务的缓存结构或者缓存实现...

呼呼南风
昨天
12
0
寻找一种易于理解的一致性算法(扩展版)

摘要 Raft 是一种为了管理复制日志的一致性算法。它提供了和 Paxos 算法相同的功能和性能,但是它的算法结构和 Paxos 不同,使得 Raft 算法更加容易理解并且更容易构建实际的系统。为了提升可...

Tiny熊
昨天
2
0
聊聊GarbageCollectionNotificationInfo

序 本文主要研究一下GarbageCollectionNotificationInfo CompositeData java.management/javax/management/openmbean/CompositeData.java public interface CompositeData { public Co......

go4it
昨天
3
0
阿里云ECS的1M带宽理解

本文就给大家科普下阿里云ECS的固定1M带宽的含义。 “下行带宽”和“上行带宽” 为了更好的理解,需要先给大家解释个词“下行带宽”和“上行带宽”: 下行带宽:粗略的解释就是下载数据的最大...

echojson
昨天
9
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部