java 线程Thread 技术--volatile关键字
java 语言中允许线程访问共享变量,为了保证共享变量能被准确和一致的更新,Java 语言提供了volatile 关键字,也就是我们所说的内存一致性;
问题抛出:(尝试去运行下面代码,以及将volatile 加上的运行结果)
/**
* 问题抛出
* @param args
*/
public class Volatile01 { public /*volatile*/ boolean flag = true; public static void main(String[] args) throws InterruptedException {
Volatile01 v =new Volatile01();
RunV r =new RunV(v);
Thread th =new Thread(r);
th.start(); //在main method to modify flag
Thread.sleep(1000);
v.flag=false;
} } class RunV implements Runnable{
Volatile01 vola ;
RunV(Volatile01 vola){
this.vola=vola;
} @Override
public void run() {
//
while(vola.flag) {} System.err.println("flag 状态转变"); } }
问题的原因是是什么呢?
根据上面的运行结果,在没有volatile 关键字的情况下,运行结果是:线程持续陷入死循环状态,flag 并没有改变;
加上volatile 后 运行结果:flag 状态转变,说明flage 已经被改变了;
请看:http://www.infoq.com/cn/articles/ftf-java-volatile 这篇文章,我大致的说一下:主要跟处理器有关,处理器为了运行的效率,不直接跟内存进行通讯;
它是先将内存的数据先读取到cpu 内部缓存(L1,L2,其他)中,操作完之后不知道什么时候才会将数据重新写到内存来修改内存中存在的值,所以在上面的例子中
在修改了flage =true 后,RunV线程是无法感知到的,依然是cpu 缓存的值;
volatile如何保证可见性呢?
依然看上文的那篇文章;里面由一些图文解释;
volatile保证原子性操作吗?是否能解决数据不一致的问题(尝试多运行如下代码,可以得到都不同的结果)?
/**
* volaile 是否支持原子性操作
* @param args
*/
public class Volatile02 { public volatile int v=0; public static void main(String[] args) throws InterruptedException, ExecutionException {
Volatile02 v =new Volatile02();
RunB r =new RunB(v);
List<Thread> theads =new ArrayList<Thread>();
for(int i=0;i<10;i++) {
theads.add(new Thread(r));
} theads.forEach((t->{
t.start();
})); theads.forEach((t->{
try {
t.join();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
})); System.out.println(v.v);
} } class RunB implements Runnable{
Volatile02 vola ;
RunB(Volatile02 vola){
this.vola=vola;
} @Override
public void run() {
for(int i=0;i<10000;i++) { vola.v++;
System.out.println(Thread.currentThread().getName());
} } }
运行得知,volatile 尽管保证了内存的可见性,但并不能保证多线程下的原子操作导致数据不一致问题;只能靠synchronized 和lock;
java 线程Thread 技术--volatile关键字的更多相关文章
- java线程学习之volatile关键字
volatile变量的主要作用:是使变量在多个线程间可见. 在java中每一个线程都会有一块工作内存区,其中存放着所有线程共享的主内存的变量值的拷贝.当线程执行时,它在自己的工作内存区操作这些变量,为 ...
- java 线程Thread 技术--线程状态与同步问题
线程技术第三篇: 线程的状态: 1. 创建状态: 当用new 操作符创建一个新的线程对象时,该线程就处于创建状态,系统不为它分配资源 2.可运行状态:当线程调用start 方法将为线程分配必须的系统资 ...
- java 线程Thread 技术--1.5 Executor Executors,ThreadPool,Queue
Executors : Executors ,就是一个线程工具类:大部分操作线程的方法,都可以在这个工具类中就行创建,执行,调用一些线程的方法: Executor : 用于执行和提交一个runnabl ...
- java 线程Thread 技术--1.5 Future与Callable
Callable: 从官方文档说起: 通过实现callable 的called 方法可以使一个任务可以返回一个结果以及可能抛出一个异常: callable 与runnable 是相似的,可以被其他线程 ...
- java 线程Thread 技术--1.5Lock 与condition 演示生产者与消费模式
在jdk 1.5 后,Java 引入了lock 锁来替代synchronized ,在使用中,lock锁的使用更加灵活,提供了灵活的 api ,不像传统的synchronized ,一旦进入synch ...
- java 线程Thread 技术--方法演示生产与消费模式
利用wait 与notifyAll 方法进行演示生产与消费的模式的演示,我们两个线程负责生产,两个线程消费,只有生产了才能消费: 在effective Java 中有说过: 1. 在Java 中 ,使 ...
- java 线程Thread 技术--线程创建源码解释
永远不要忘记最基础的东西,只有把最基础的知识打牢靠,才能够使你走的更远,我将从今天开始,进行线程知识的回顾,一些常用知识点,以及java1.5 引入的并发库,进行详细的讲解与总结 创建线程的目的是为了 ...
- java 线程Thread 技术--线程方法详解
Thread 类常用的方法与Object类提供的线程操作方法:(一个对象只有一把锁
- java 线程Thread 技术--创建线程的方式
在第一节中,对线程的创建我们通过看文档,得知线程的创建有两种方式进行实现,我们进行第一种方式的创建,通过继承Thread 类 ,并且重写它的run 方法,就可以进行线程的创建,所有的程序执行都放在了r ...
随机推荐
- 邮件报警以及服务端能否ping通客户端的小例子(三)
就这个小小的东西,弄了一天,弄的头晕眼花,毕竟第一次弄这个,记录下来,若干年之后,回看这些笔记,不知是什么样的感想,哈哈.我学一个东西的时候喜欢系统的来,一点一点的来,做这个的时候想法很 ...
- 【转】使用VisualStudio完成自动化C++代码生成和编译工作(GacUI)
使用VisualStudio完成自动化C++代码生成和编译工作(GacUI) GacUI终于进入制作dll的阶段了.昨天上传了一个新的工程,在Vczh Library++3.0(E:\Code ...
- docker安装solr集群5.3.1
docker-compose.yml: version: '3' services: zookeeper-A: image: zookeeper:3.4.11 ports: - "12181 ...
- How to load custom styles at runtime (不会翻译,只有抄了 )
原文 :http://blogs.embarcadero.com/sarinadupont/2013/10/16/how-to-load-custom-styles-at-runtime/ How t ...
- c++11 关于typelist的foreach
建好一个typelist,其中都是类型信息而已,很重要的一个应用,循环迭代干些事情. 看了下boost的for_each实现,用我自己的typelist,大概代码如下: template<typ ...
- Maya中输出alembic文件的方法
Maya中输出alembic文件是有现成api调用的,与maya中大部分api一样,这个功能参数的传入是非常类似mel的,本质上讲都是kwargs类型的参数,所以我们传入的参数就需要整理成类似于mel ...
- php语法基础(相比C语言)
前言 php的语法跟C语言很类似,相信有一定C的基础的人学起来会非常快. 本篇主要介绍php相比C语言有差异的地方 php代码标记 ASP标记:<% 代码 %> 短标记:<? 代码 ...
- Percona XtraDB Cluster vs Galera Cluster vs MySQL Group Replication
Percona XtraDB Cluster vs Galera Cluster vs MySQL Group Replication Overview Galera Cluster 由 Coders ...
- (整理)MySQL_REHL6.5 MySQL5.5 中文支持问题
1 查看字符集命令 SHOW VARIABLES LIKE ‘character%’; 2 修改my.cnf文件中来实现中文支持 2.1 复制my.cnf 安装结束后,etc目录下并没有my.cnf文 ...
- SpringCloud系列三:SpringSecurity 安全访问(配置安全验证、服务消费端处理、无状态 Session 配置、定义公共安全配置程序类)
1.概念:SpringSecurity 安全访问 2.具体内容 所有的 Rest 服务最终都是暴露在公网上的,也就是说如果你的 Rest 服务属于一些你自己公司的私人业务,这样的结果会直接 导致你信息 ...