我们先来看一段代码:

①.线程类,用全局布尔值控制线程是否结束,每隔1s打印一次当前线程的信息
  1. package com.multiThread.thread;
  2. publicclassPrintStringimplementsRunnable{
  3. privateboolean isContinuePrint =true;
  4. @Override
  5. publicvoid run(){
  6. while(isContinuePrint){
  7. try{
  8. System.out.println("current threadId is "+Thread.currentThread().getId()+",threadName is"+Thread.currentThread().getName()+",threadPriority "+Thread.currentThread().getPriority());
  9. Thread.sleep(1000);
  10. }catch(InterruptedException e){
  11. e.printStackTrace();
  12. }
  13. }
  14. System.out.println("Thread is stop!");
  15. }
  16. publicboolean isContinuePrint(){
  17. return isContinuePrint;
  18. }
  19. publicvoid setContinuePrint(boolean isContinuePrint){
  20. this.isContinuePrint = isContinuePrint;
  21. }
  22. }
②.测试类
  1. package com.multiThread.test.common;
  2. import com.multiThread.thread.PrintString;
  3. publicclassVolatileTest{
  4. publicstaticvoid main(String[] args){
  5. PrintString printString =newPrintString();
  6. Thread t =newThread(printString);
  7. t.start();
  8. try{
  9. Thread.sleep(2000);
  10. printString.setContinuePrint(false);
  11. }catch(InterruptedException e){
  12. e.printStackTrace();
  13. }
  14. }
  15. }
打印结果:
  1. current threadId is 8,threadName isThread-0,threadPriority 5
  2. current threadId is 8,threadName isThread-0,threadPriority 5
  3. Thread is stop!
 
以上这段程序在我本地的eclipse上运行完全没有问题,但是一段以服务器端的参数来运行则会出现问题。
我们修改一下eclipse的运行方式,带上参数-server来运行这段代码,擦,运行结果还是这样,又没成功,我命名是win7+jdk64位啊。
先不管了,按照书上说的,这块停不下来。那为什么停不下来呢?因为服务器为了兼顾性能直接从当前线程的工作内存中获取的值,没有从主内存中取。而main函数里的操作是把主内存的数据给更新了,听起来类似于程序的读缓存没查库的操作。
 
解决的方式就是为变量此变量加上volatile关键字来修饰。volatile关键字修饰的变量会强制从主内存中读取数据,保证数据的可见性。
此关键字的应用场景为:多线程中可以感知实例变量被更改了。并且可以获得最新的值使用,也就是多线程读取共享变量时可以获得最新的值使用
  1. privatevolatileboolean isContinuePrint =true;
 
附带volatile关键字的工作图:
 
当然,此处也可以采用synchronize的方式来处理,不过synchronize和volatile关键字的作用是不同的。
这里要注重强调一下二者的区别和作用:
volatile:强制从主内存读取数据,保证数据的可见性。volatile的操作不是原子性的。
synchronize:同步操作,保证一次监视对象一次只有一个线程去处理。synchronize本身也可以保证数据的可见性,同时更重要的是用来保证数据的同步性。
 
多线程这块的处理都是围绕着数据的同步性、可见性和原子性来操作的,记住这个原则就OK。
下一章我们来看一下和原子性有关的操作。
 
用一张图来描述变量在内存中的工作流程:
 
 

多线程(三)~多线程中数据的可见性-volatile关键字的更多相关文章

  1. 多线程(三) java中线程的简单使用

    java中,启动线程通常是通过Thread或其子类通过调用start()方法启动. 常见使用线程有两种:实现Runnable接口和继承Thread.而继承Thread亦或使用TimerTask其底层依 ...

  2. Java多线程6:synchronized锁定类方法、volatile关键字及其他

    同步静态方法 synchronized还可以应用在静态方法上,如果这么写,则代表的是对当前.java文件对应的Class类加锁.看一下例子,注意一下printC()并不是一个静态方法: public ...

  3. java中 static,final,transient,volatile关键字的作用

    static 和final static  静态修饰关键字,可以修饰 变量,程序块,类的方法: 当你定义一个static的变量的时候jvm会将将其分配在内存堆上,所有程序对它的引用都会指向这一个地址而 ...

  4. 多线程(三) iOS中的锁

    锁的类别:互斥锁,递归锁,条件锁,自旋锁等 锁的实现方式:NSLock,NSRecursiveLock, NSConditionLock,@synchronized,GCD的信号量等 下面说一下常用的 ...

  5. Java多线程(三) 多线程间的基本通信

    多条线程在操作同一份数据的时候,一般需要程序去控制好变量.在多条线程同时运行的前提下控制变量,涉及到线程通信及变量保护等. 本博文主要总结:①线程是如何通信  ②如何保护线程变量 1.Java里的线程 ...

  6. Java 并发和多线程(三) 多线程的代价 [转]

    原文链接:http://tutorials.jenkov.com/java-concurrency/costs.html 作者:Jakob Jenkov     翻译:古圣昌        校对:欧振 ...

  7. 多线程(三)多线程同步_基本介绍及mutex互斥体

    同步进制的引入为了解决以下三个主要问题:1.控制多个线程之间对共享资源访问,保证共享资源的完整性例如:线程A对共享资源进行写入,线程B读取共享资源2.确保多个线程之间的动作以指定的次序发生例如:线程B ...

  8. java多线程(三):多线程单例模式,双重检查,volatile关键字

    一.事先准备 首先准备一个运行用的代码: public class Singleton { public static void main(String[] args) { Thread[] thre ...

  9. 从零开始了解多线程知识之开始篇目 -- jvm&volatile

    CPU多核缓存存储结构图 电脑存储结构概念 多CPU 一个现代计算机通常由两个或者多个CPU,如果要运行多个程序(进程)的话,假如只有 一个CPU的话,就意味着要经常进行进程上下文切换 因为单CPU即 ...

随机推荐

  1. java 连接 Redis

    使用 jedis-2.9.0.jar 包 连接 Docker 中的 Redis 容器. package redisTest; /** * @Author:YangLianjun * @Descript ...

  2. Android 数据库框架GreenDao使用

    1.GreenDao3介绍 (1)基本概念 (2)GreenDao3工作原理 (3)GreenDao优点 (4)GreenDao3版本的改进 2.GreenDao3的相关配置概念介绍 (1)配置项目( ...

  3. 网站安装 https 证书

    1.点击进入官网  数安时代 2.点击选择你需要的ssl 证书 3.点击进入选择 免费申请 ,填写你需要 安装 ssl 证书 的域名 4.根据你的需求选择,我这里选择的是 数安时代 ,接下来按照步骤操 ...

  4. python-is,==

    在讲is和==这两种运算符区别之前,首先要知道Python中对象包含的三个基本要素,分别是:id(身份标识).python type()(数据类型)和value(值).is和==都是对对象进行比较判断 ...

  5. 关于webpack 以及 webpack配置和常用插件的学习记录 (1)

    主要概念: Entry :   webpack的入口,构建的第一步从entry开始. Output :   输出,经过webpack处理后的得到最终想要的代码. Loader :   模块转换工具,把 ...

  6. ansys 14.0

    张建伟等.2012.12 人民邮电 一天一本书,这种感觉 真是爽啊. 但我觉得什么也没学到. 话说回来,此authors 确实书写得比较一般,实例不如百度文档上的WORD实例,理论不如我看的那本CFD ...

  7. Emit生成特定接口的类

    参考 动态生成类 http://www w2bc com/Article/44799 http://www.cnblogs.com/yingql/archive/2009/03/24/1420914. ...

  8. log4j详解与实战

    [转自] http://www.iteye.com/topic/378077 log4j是一个非常强大的log记录软件,下面我们就来看看在项目中如何使log4j. 首先当然是得到log4j的jar档, ...

  9. HTML中body内常用标签

    基本标签 <b>加粗</b> <i>斜体</i> <u>下划线</u> <s>删除<s/> <p& ...

  10. vim(三)golang代码跳转配

    在golang的代码里跳来跳去.... godef 安装 跳转是通过godef实现,godef的安装目录一般是$GOBIN,只要让godef命令在$PATH下即可 godef 命令安装: go get ...