java并发进程共享变量_JAVA并发编程学习:共享对象
可见性
在一个单线程程序中,如果向一个变量先写入值,然后在没有写干涉的情况下读取这个变量,会得到相同的返回值。但是当读和写发生在不同的线程中时,就不能保证读线程及时地读取其他线程写入的值。在JAVA中所有实例域、静态域和数组元素存储在堆内存中,堆内存在线程之间共享,局部变量,方法定义参数和异常处理器参数不会在线程之间共享,它们不会有内存可见性问题,也不受内存模型的影响。为了确保跨线程写入的内存可见性,必须使用同步机制
下例是主线程和读线程两个线程访问共享变量ready和number。主线程启动读线程,然后把number的值设为42,ready的值赋为true。读线程进行循环,直到发现ready的值变为true,然后打印出number的值。虽然看起来会输出42,但事实上,它很有可能打印出0,或者根本不会终止。这是因为它没有使用恰当的同步机制,没能保证主线程写入ready和number的值对读线程是可见的
package com.henrysun.javaSE.bfbc;
/**
* 在没有同步的情况下共享变量(不要这样做)
* 重排序现象
* @author Sam Flynn
*
*/
public class GongXiangBianLiangReordering {
private static boolean ready;
private static intnumber;
private static class ReaderThread extends Thread
{
public void run()
{
while(!ready)
{
Thread.yield();
}
System.out.println(number);
}
}
/**
* @param args
*/
public static void main(String[] args) {
new ReaderThread().start();
number=42;
ready=true;
}
}
重排序现象
上面的例子中,可能会打印0,因为早在对number赋值之前,主线程就已经写入ready并使之对读线程可见,这叫做“重排序(reordering)”现象。
这里处理器A和处理器B可以同时把共享变量写入自己的写缓冲区(A1,B1),然后从内存中读取另一个共享变量(A2,B2),最后才把自己写缓存区中保存的脏数据刷新到内存中(A3,B3)。当以这种时序执行时,程序就可以得到x = y = 0的结果
锁和可见性
锁不仅仅是关于同步互斥的,也是关于内存可见的。当线程A执行一个同步块时,线程B也随后进入了被同一个锁监视的同步块中,这时可以保证,在锁释放之前对A的可见的变量的值,B获得锁之后同样是可见的。换句话说,当B执行到A相同的锁监视的同步块时,A在同步块之中或之前所做的每件事,对B都是可见的。为了保证所有线程都能够看到共享的,可变变量的最新值,读取和写入线程必须使用公共的锁进行同步
Volatile变量
当一个域声明为volatile类型后,编译器与运行时会监视这个变量:它是共享的,而且对它的操作不会与其他的内存操作一起被重排序。volatile变量不会缓存在寄存器或者缓存在其他对处理器隐藏的地方。所以,读一个volatile类型的变量时,总会返回由某一线程写入的最新值
但是volatile变量的操作不会加锁,也就不会引起执行线程的阻塞,所以它只是轻量级的同步机制,正确使用volatile变量的方式包括:用于确保它们所引用的对象状态的可见性,或者用于标识重要的生命周期事件(比如初始化或关闭)的发生,即通常被当作标识完成、中断、状态的标记使用
尽管volatile也可以用来标识其他类型的状态信息,但是决定这样做之前请格外小心。比如,volatile的语义不足以使自增操作(count++)原子化,除非你能保证只有一个线程对变量执行写操作。加锁可以保证可见性与原子性,而volatile变量只能保证可见性
只有满足了下面的标准,才能使用volatile变量
写入变量时并不依赖变量的当前值;或者能够确保只有单一的线程修改变量的值
变量不需要与其他的状态变量共同参与不变约束
而且,访问变量时,没有其他的原因需要加锁
ThreadLocal
java并发进程共享变量_JAVA并发编程学习:共享对象相关推荐
- java中解决脏读_java并发编程学习之脏读代码示例及处理
使用interrupt()中断线程 当一个线程运行时,另一个线程可以调用对应的Thread对象的interrupt()方法来中断它,该方法只是在目标线程中设置一个标志,表示它已经被中断,并立即 ...
- java公平锁和非公平锁_java并发编程学习之再谈公平锁和非公平锁
在java并发编程学习之显示锁Lock里有提过公平锁和非公平锁,我们知道他的使用方式,以及非公平锁的性能较高,在AQS源码分析的基础上,我们看看NonfairSync和FairSync的区别在什么地方 ...
- java投票锁_Java并发编程锁之独占公平锁与非公平锁比较
Java并发编程锁之独占公平锁与非公平锁比较 公平锁和非公平锁理解: 在上一篇文章中,我们知道了非公平锁.其实Java中还存在着公平锁呢.公平二字怎么理解呢?和我们现实理解是一样的.大家去排队本着先来 ...
- java逸出_Java并发编程 - 对象的共享
编写正确的并发程序,关键问题在于:在访问共享的可变状态时需要进行正确的管理.同步代码块和同步方法可以确保以原子的方式执行操作,同步还有另一个重要的方面:内存可见性. 可见性 为了确保多个线程之间对内存 ...
- java计算时间差_JAVA并发编程三大Bug源头(可见性、原子性、有序性),彻底弄懂...
原创声明:本文转载自公众号[胖滚猪学编程] 某日,胖滚猪写的代码导致了一个生产bug,奋战到凌晨三点依旧没有解决问题.胖滚熊一看,只用了一个volatile就解决了.并告知胖滚猪,这是并发编程导致的 ...
- java volatile 原子性_Java并发编程之验证volatile不能保证原子性
Java并发编程之验证volatile不能保证原子性 通过系列文章的学习,凯哥已经介绍了volatile的三大特性.1:保证可见性 2:不保证原子性 3:保证顺序.那么怎么来验证可见性呢?本文凯哥(凯 ...
- java cas机制_java并发编程中的CAS机制,你理解嘛?
学习Java并发编程,CAS机制都是一个不得不掌握的知识点.这篇文章主要是从出现的原因再到原理进行一个解析.希望对你有所帮助. 一.为什么需要CAS机制? 为什么需要CAS机制呢?我们先从一个错误现象 ...
- JAVA并发编程实战——共享对象
目录 思维导图 1. 可见性 1. 1 过期数据 1.2 锁和可见性 1.3 Volatile变量 2. 发布和逸出 2.1 安全构建实践 3. 线程封闭 3.1 栈限制 3.2 ThreadLoca ...
- java 线程工厂_Java并发编程:Java的四种线程池的使用,以及自定义线程工厂
引言 通过前面的文章,我们学习了Executor框架中的核心类ThreadPoolExecutor ,对于线程池的核心调度机制有了一定的了解,并且成功使用ThreadPoolExecutor 创建了线 ...
最新文章
- Ubuntu中的minicom
- Docker + FastDFS + Spring Boot 一键式搭建分布式文件服务器
- ubuntu 终端批量复制文件_《卡死你3000》批量文件复制命令详解
- oracle 10g 用户管理笔记
- ???????????? no permissions的解决办法 解决网上方法行不通的问题
- iOS开发之ReplayKit框架学习
- 计算机图形与游戏技术,宾夕法尼亚大学计算机图形与游戏技术研究生Offer及录取要求...
- Redis集群监控RedisClusterManager
- 第九届(2018)蓝桥杯 山东省赛解题报告(题目+分析+代码)
- H5 中 bordercolorlight 属性的用法及作用
- Java关键字(六)——super
- 收藏|2021年浅谈多任务学习
- Java 接口,多态
- 使用FlashCS6制作cocos2d-x动作脚本的思路整理
- 人才测评技术与应用【1】
- (原创)分享一下最近搞的tiny210V2从nand启动支持(K9GAG08U0F).
- 新浪邮箱模拟登录java
- PDF文件电子签名怎么做?分享一个好用的签名工具
- 谷歌发现利用零日漏洞的攻击、黑客通过漏洞入侵红十字会|2月17日全球网络安全热点
- 云的新出路迷你云?轻松搭建私有云平台 转载7