Java JUC 简介

在 Java 5.0 提供了 java.util.concurrent (简称JUC )包,在此包中增加了在并发编程中很常用的实用工具类,用于定义类似于线程的自定义子系统,包括线程池、异步 IO 和轻量级任务框架。提供可调的、灵活的线程池。还提供了设计用于多线程上下文中的 Collection 实现等。

内存可见性

内存可见性(Memory Visibility)是指当某个线程正在使用对象状态而另一个线程在同时修改该状态,需要确保当一个线程修改了对象状态后,其他线程能够看到发生的状态变化。

可见性错误是指当读操作与写操作在不同的线程中执行时,我们无法确保执行读操作的线程能适时地看到其他线程写入的值,有时甚至是根本不可能的事情。

 我们可以通过同步来保证对象被安全地发布。除此之外我们也可以使用一种更加轻量级的 volatile 变量。

volatile 关键字

Java 提供了一种稍弱的同步机制,即 volatile 变量,用来确保将变量的更新操作通知到其他线程。可以将 volatile 看做一个轻量级的锁,但是又与锁有些不同:

  • 对于多线程,不是一种互斥关系
  • 不能保证变量状态的“原子性操作”
 /*
* 当有多个线程时,虚拟机会为每个 线程开辟一个独立的缓存区域,当某个线程去访问共享变量(存放在主存区(堆中))
* 会把 主存中的变量 复制一份到自己的缓存中,在自己的缓存中去操作,改变这个变量的值,然后再去更新主存中的变量的值
* (三步:1.线程拷贝一份到自己的缓存中 2.在缓存中修改变量的值 3.将修改后的值回送给主存,更新主存中变量的值)
* 若另外一个线程执行的操作比较快(如这里的while(true)),还等不及子线程去更新主存中的数据,这个线程就去读 主存中变量的值,拿到的是子线程处理之前的变量的值
* 此时 两个线程各自缓存区的关于这个变量的值 是不同的
*
* 所以说,对于线程之间来说,内存是不可见的,可以使用 volatile,来保证内存中的数据可见
* (即可以理解为:使用volatile修饰变量后,不拿到 各自线程的缓存中操作这个变量了,直接在 主存中操作变量,
* 这样变量一修改,主存就能得到 这个变量 的最新值,其他线程能改看到这个线程即时发生的变化)
* */ /*
* 一:volatile 关键字 :当多个线程进行操作共享数据时,可以保证内存中的数据可见
* 相较于synchronize,是一种较为轻量级的同步策略(性能比 synchronize 要高一些)
*
* 注:1.volatile 不具备互斥性
* 2.volatile 不能保证变量的“原子性”
*
* */
public class TestVolatile {
public static void main(String[] args) {
MyThread td = new MyThread();
new Thread(td).start(); //这里有一个主线程和一个子线程,两个线程同时都在执行,子线程的执行首先为flag赋值为false,然后进入休眠,休眠完后将flag 改为true
//主线程和子线程同步进行,但是因为flag的值一直为false,所以无法跳出循环,要等到休眠完毕,flag 变为 true
//因为这里flag是volatile变量,所以子线程对flag 修改,主线程是能够看到的
while (true) {
//使用synchronized等待 td 线程完成,再去主存中去读 flag的值,将flag的值加载到自己的缓存中
//synchronized (td) {
if (td.isFlag()) {
System.out.println("---------");
break;
}
//}
}
}
} class MyThread implements Runnable {
private volatile boolean flag = false; //加入了 volatile ,保证线程之间的内存相互可见 @Override
public void run() {
try {
Thread.sleep(1000);
} catch (InterruptedException e) { } flag = true;
System.out.println("子线程:flag = " + flag);
} public boolean isFlag() {
return flag;
} public void setFlag(boolean flag) {
this.flag = flag;
}
}

1.volatile关键字 内存可见性的更多相关文章

  1. 二、volatile关键字 - 内存可见性

    1.内存可见性 ​ (程序在运行时,jvm会为每一个执行任务的线程都分配一个独立的缓存,用于提高效率) ​ 我觉得可以这样来理解: ​ 内存:啥是内存?就是可以理解成电脑当中的内存条,程序创建个变量, ...

  2. Volatile 关键字 内存可见性

    1.问题引入 实现线程: public class ThreadDemo implements Runnable { private boolean flag = false; @Override p ...

  3. java多线程 -- volatile 关键字 内存 可见性

    内存可见性(Memory Visibility) 1 内存可见性(Memory Visibility)是指当某个线程正在使用对象状态而另一个线程在同时修改该状态,需要确保当一个线程修改了对象状态后,其 ...

  4. 1. volatale 关键字 -内存可见性

    package com.gf.demo01; /** * 一.volatile 关键字:但多个线程进行操作共享数据时,可以保证内存中数据可见性. * */ public class TestVolat ...

  5. 1、JUC--volatile 关键字-内存可见性

    Java JUC简介 在 Java 5.0 提供了 java.util.concurrent (简称JUC )包,在此包中增加了在并发编程中很常用的实用工具类,用于定义类似于线程的自定义子系统,包括线 ...

  6. JUC 并发编程--05, Volatile关键字特性: 可见性, 不保证原子性,禁止指令重排, 代码证明过程. CAS了解么 , ABA怎么解决, 手写自旋锁和死锁

    问: 了解volatile关键字么? 答: 他是java 的关键字, 保证可见性, 不保证原子性, 禁止指令重排 问: 你说的这三个特性, 能写代码证明么? 答: .... 问: 听说过 CAS么 他 ...

  7. 全面理解Java内存模型(JMM)及volatile关键字(转载)

    关联文章: 深入理解Java类型信息(Class对象)与反射机制 深入理解Java枚举类型(enum) 深入理解Java注解类型(@Annotation) 深入理解Java类加载器(ClassLoad ...

  8. 全面理解Java内存模型(JMM)及volatile关键字

    [版权申明]未经博主同意,谢绝转载!(请尊重原创,博主保留追究权) http://blog.csdn.net/javazejian/article/details/72772461 出自[zejian ...

  9. Java并发编程:JMM (Java内存模型) 以及与volatile关键字详解

    目录 计算机系统的一致性 Java内存模型 内存模型的3个重要特征 原子性 可见性 有序性 指令重排序 volatile关键字 保证可见性和防止指令重排 不能保证原子性 计算机系统的一致性 在现代计算 ...

随机推荐

  1. web手工项目02-注册功能输入分析,处理,输出方法-测试用例及缺陷编写-首页轮播图和购物车

    web手工项目第二天笔记 昨日回顾 搭建测试环境(WAMP,phpStudy,tpshop项目文件) 熟悉项目(四个步骤,三个来源) 项目测试流程(需求评审,测试计划与方案,测试用例设计与评审,测试执 ...

  2. PAT 甲级 1036 Boys vs Girls (25 分)(简单题)

    1036 Boys vs Girls (25 分)   This time you are asked to tell the difference between the lowest grade ...

  3. Python源码编译安装,supervisor配置管理

    apt-get remove 会删除软件包而保留软件的配置文件 apt-get purge 会同时清除软件包和软件的配置文件 virtualenv -p /usr/local/bin/python3. ...

  4. 搭建Android与多ble蓝牙设备并发通讯小框架

    此框架支持多种不同类型的ble设备,同时连接.收发数据,互不干扰.比如APP同时连两个LED蓝牙灯.两个手环.一个蓝牙加热器,当然连接单个ble设备,或者只连接一种ble设备同样适用本框架. 前言 小 ...

  5. git merge仓

    git merge --no-ff branch 合并指定代码 如果有冲突 git mergetool   可视化解决冲突, qa! 全退出 如果修复失败 git checkout branch -f ...

  6. win7/Ubuntu双系统给Ubuntu扩大硬盘

    问题 电脑上装了windows 7和ubuntu双系统,起初分配硬盘的时候,给ubuntu划分的量较少,如今硬盘空间已不够用,另外挂载分区也不够方便.希望能在不重装系统的情况下,从win7的硬盘中分一 ...

  7. 用Inno setup制作以管理员权限启动的安装包

    inno setup制作的安装包,默认是不需要管理员权限启动的.我们制作安装包,往往需要做一些设置工作,这些设置工作可能用到管理员权限.使用Resource Hacker修改inno setup资源, ...

  8. gcc/clang编译带pthread.h头文件的源码时需要的参数

    今天敲了一个小程序,编译时出现错误:undefined reference pthread_create 原来由于pthread库不是Linux系统默认的库,连接时需要使用库libpthread.a, ...

  9. service 方法和doGet、doPost方法的区别

    Service方法和doGet和doPost方法的区别service:     可以处理get/post方式的请求,如果servlet 中有service方法,会优先调用service方法进行处理do ...

  10. Jmeter逻辑控制器: If控制器的解读

    Jmeter官网其实有很详细的文档,点此跳转到官网,下面我来解读一下官网的文档,如有错误,欢迎指出. 一.官网解读 Name 在结果树中显示的名字. Comments 备注.相当于代码中的注释. Ex ...