开始全文之前,先铺垫一下jvm基础知识以及线程栈:

JVM栈是线程私有的,每个线程创建的同时都会创建JVM栈,JVM栈中存放的为当前线程中局部基本类型的变量(java中定义的八种基本类型:boolean、char、byte、short、int、long、float、double)、部分的返回结果以及Stack Frame,非基本类型的对象在JVM栈上仅存放一个指向堆上的地址。

 
 
 
接下来说说volatile:

用volatile修饰的变量,线程在每次使用变量的时候,都会读取变量修改后的最的值。volatile很容易被误用,用来进行原子性操作。如果要深入了解volatile关键字的作用,就必须先来了解一下JVM在运行时候的内存分配过程。在 java 垃圾回收整理一文中,描述了jvm运行时刻内存的分配。其中有一个内存区域是jvm虚拟机栈,每一个线程运行时都有一个线程栈,线程栈保存了线程运行时候变量值信息。当线程访问某一个对象时候值的时候,首先通过对象的引用找到对应在堆内存的变量的值,然后把堆内存变量的具体值load到线程本地内存中,建立一个变量副本,之后线程就不再和对象在堆内存变量值有任何关系,而是直接修改副本变量的值,在修改完之后的某一个时刻(线程退出之前),自动把线程变量副本的值回写到对象在堆中变量。这样在堆中的对象的值就产生变化了。下面一幅图描述这写交互!

 
 
有了以上知识做铺垫,接下来直接上代码:
package thread;

public class VolatiDemo1
{
private static volatile boolean flag = true;
private static final ThreadLocal <Integer> length = new ThreadLocal <Integer>(){
@Override
protected Integer initialValue()
{
return 60;
}
}; public static void main(String[] args)
{
//模拟兔子
new Thread(new Runnable()
{
int rabbitLength = 0;
@Override
public void run()
{
while(flag){
try
{
Thread.sleep(1000);
rabbitLength = rabbitLength + 3;
System.out.println("兔子跑了 rabbitLength " + rabbitLength + " 米,还剩下:"+
(length.get() - rabbitLength) +" 米--------------------"); if(rabbitLength == length.get())
{
System.out.println("兔子获得第一名");
flag = false;
}
} catch (InterruptedException e)
{
e.printStackTrace();
}
}
}
}).start(); //模拟乌龟
new Thread(new Runnable()
{
int tortoiseLength = 0;
@Override
public void run()
{
while(flag){
try
{
Thread.sleep(1000);
tortoiseLength = tortoiseLength + 1;
System.out.println("乌龟 跑了 tortoiseLength " + tortoiseLength + " 米,还剩下 "
+ (length.get() -tortoiseLength) +"米"); if(tortoiseLength == length.get())
{
System.out.println("乌龟获得第一名");
flag = false;
}
} catch (InterruptedException e)
{
e.printStackTrace();
}
}
}
}).start(); try
{
Thread.sleep(8000);
flag = false;
} catch (InterruptedException e)
{
e.printStackTrace();
}
}
}

  

 

多线程之volatile关键字(五)的更多相关文章

  1. Java多线程之volatile关键字《一》

    关键字volatile的主要作用是使变量在多个线程间可见. 1.关键字volatile与死循环 如果不是在多继承的情况下,使用继承Thread类和实现Runnable接口在取得程序运行的结果上并没有什 ...

  2. java多线程之volatile关键字

    public class ThreadVolatile extends Thread { public boolean flag=true; @Override public void run() { ...

  3. JAVA多线程之volatile 与 synchronized 的比较

    一,volatile关键字的可见性 要想理解volatile关键字,得先了解下JAVA的内存模型,Java内存模型的抽象示意图如下: 从图中可以看出: ①每个线程都有一个自己的本地内存空间--线程栈空 ...

  4. Java并发编程之volatile关键字解析

    一内存模型的相关概念 二并发编程中的三个概念 三Java内存模型 四深入剖析volatile关键字 五使用volatile关键字的场景 volatile这个关键字可能很多朋友都听说过,或许也都用过.在 ...

  5. Java多线程之volatile详解

    本文目录 从多线程交替打印A和B开始 Java 内存模型中的可见性.原子性和有序性 Volatile原理 volatile的特性 volatile happens-before规则 volatile ...

  6. 多线程之volative关键字

    目录 轻量级同步机制:volative关键字 volative的作用 volatile非原子特性 volatile与synchronized比较 常用原子类进行自增自减操作 CAS 使用CAS原理实现 ...

  7. Java 并发编程之volatile关键字解析

    摘录 1. 计算机在执行程序时,每条指令都是在CPU中执行的,而执行指令过程中,势必涉及到数据的读取和写入.由于程序运行过程中的临时数据是存放在主存(物理内存)当中的,这时就存在一个问题,由于CPU执 ...

  8. 线程之-volatile

    线程作为java面试中必须要掌握的一环,volatile多少也会在面试中被问到,所以就需要好好研究下,以面对面试官的问题. 首先要清楚线程不安全是什么原因引起的,需要明白计算机的cpu执行每条指令时都 ...

  9. Java并发编程之volatile关键字

    大概是因为项目.业务的原因,工作上几乎还没有使用过多线程相关的功能,相关知识差不多都忘了,所以最近补一下基础. volatile用来修饰共享变量,volatile变量具有 synchronized 的 ...

随机推荐

  1. PM2自动发布本地项目到服务器

    (一)开发环境 本地服务器 Ubunt14.04 远程服务器Ubuntu16.04 发布软件PM 2 (二)发布介绍 本地和我们的远程服务器,必须都安装有git,pm2,以及nodejs环境.实际上配 ...

  2. Java 多线程概念

    1.为什么要使用多线程: 更多的处理器核心. 更快的响应时间. 更好的变成模型. 2.线程的优先级: 现代操作系统基本采用时分的形式调度运行的线程,操作系统会分出一个个的时间片,线程会分配到若干时间片 ...

  3. Win7环境下配置FTP

    1.打开 控制面板-->程序和功能-->打开或关闭Windows资源,在弹出的窗体里找到 “Internet信息服务”,展开后选择“Ftp服务器",然后点击"确定&qu ...

  4. Spring连接数据库

    public class Book { private int bookid; private String bookname; private String bookauthor; private ...

  5. Servlet 示例

    引入jar包: servlet-api.jar ParameterServlet.java package com.mousewheel.springmvc; import java.io.IOExc ...

  6. JAVA基础之字节流与字符流

    个人理解: IO流就是将数据进行操作的方式,因为编码的不同,所以对文件的操作就产生两种.最好用字节流,为了方便看汉字等,(已经确定文字的话)可以使用字符流.每个流派也就分为输入和输出,这样就可以产生复 ...

  7. Vue Scroller:Vue 下拉刷新及无限加载组件

    Vue Scroller Vue Scroller is a foundational component ofVonic UI. In purpose of smooth scrolling, pu ...

  8. Hbase region查找过程

    HBase的table是该region切分的,client操作一个row的时候,如何知道这个row对应的region是在哪台Region server上呢?这里有个region location过程. ...

  9. mui实现图片更换(暂未上传)

    页面中有默认的图片,触发type为file的input时,更换图片,这个是mui移动端的项目,算了,不多说,开码 首先,先在html页面中设置样式,样式我就不给了,贴个布局 <div class ...

  10. Echarts获取数据绘制图表

    这次是利用mui框架实现一个手机移动端的项目.基本的框架已经实现,主要来获取数据实现一个图表的展示. 首先引入插件:echarts.js <script src="../resourc ...