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 ...
随机推荐
- tmpfs临时文件系统,是一种基于内存的文件系统
在Linux系统内存中的虚拟磁盘映射,可以理解为使用物理内存当做磁盘,利用这种文件系统,可以有效提高在高并发场景下的磁盘读写,但是重启后数据会丢失. 1.查看tmpfs路径 (系统默认开启,大小约为物 ...
- python中的copy.copy和copy.deepcopy
一个例子就搞清楚 import copy a = [1, 2, 3, 4, ['a', 'b']] #原始对象 b = a #赋值,传对象的引用 c = copy.copy(a) #对象拷贝,浅拷贝 ...
- Windows Azure Virtual Network (13) 跨数据中心之间的虚拟网络点对点连接VNet Peering
<Windows Azure Platform 系列文章目录> 今天是大年初二,首先祝大家新年快乐,万事如意. 在笔者之前的文章中:Windows Azure Virtual Networ ...
- sql server紧急状态下登录脚本
--打开xp_cmdshell功能 EXEC [sys].[sp_configure] @configname = 'xp_cmdshell', -- varchar(35) @configv ...
- windows server 2008 r2 x64 enterprise service pack1中aspjpeg.dll安装
官网地址:http://persits.com/ 64位:http://www.persits.com/aspjpeg64.exe sn:lptn9dQO1enAePAXB2wFaCZawYWzfm0 ...
- bzoj5048: 塌陷的牧场
Description 农夫小Q将他的奶牛们饲养在一个长n宽m的矩形网格牧场中.行从上到下依次编号为1到n,列从左往右依次编号为1 到m.为了防止奶牛们逃跑,小Q在牧场外圈安装了一排电网,只要奶牛走出 ...
- solr6.4.1搜索引擎(3)增量同步mysql数据库
尚未实现首次同步mysql数据库的,请参考我的另一篇文章http://www.cnblogs.com/zhuwenjoyce/p/6512378.html(solr6.4.1搜索引擎同步mysql数据 ...
- MySQL 之 MHA + ProxySQL + keepalived 实现读写分离,高可用(一)
准备服务器: docker network create --subnet=192.168.0.0/16 staticnetdocker run -d --privileged -v `pwd`/my ...
- ajax多个请求执行顺序
先说结论再说原因 结论:比如点击事件触发了两个ajax请求或者更多的请求,是没有执行顺序的,各个请求的快慢完全取决于返回的快慢,或许你在浏览器调试窗口看见的是先发了一个请求,再发了一个,但是完全没有等 ...
- JS截取URL地址参数
var url = window.location.search; 截取?r= 后面的参数var url = window.location.href;var urlss= urlssplit('co ...