可见性

在一个单线程程序中,如果向一个变量先写入值,然后在没有写干涉的情况下读取这个变量,会得到相同的返回值。但是当读和写发生在不同的线程中时,就不能保证读线程及时地读取其他线程写入的值。在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并发编程学习:共享对象相关推荐

  1. java中解决脏读_java并发编程学习之脏读代码示例及处理

    使用interrupt()中断线程     当一个线程运行时,另一个线程可以调用对应的Thread对象的interrupt()方法来中断它,该方法只是在目标线程中设置一个标志,表示它已经被中断,并立即 ...

  2. java公平锁和非公平锁_java并发编程学习之再谈公平锁和非公平锁

    在java并发编程学习之显示锁Lock里有提过公平锁和非公平锁,我们知道他的使用方式,以及非公平锁的性能较高,在AQS源码分析的基础上,我们看看NonfairSync和FairSync的区别在什么地方 ...

  3. java投票锁_Java并发编程锁之独占公平锁与非公平锁比较

    Java并发编程锁之独占公平锁与非公平锁比较 公平锁和非公平锁理解: 在上一篇文章中,我们知道了非公平锁.其实Java中还存在着公平锁呢.公平二字怎么理解呢?和我们现实理解是一样的.大家去排队本着先来 ...

  4. java逸出_Java并发编程 - 对象的共享

    编写正确的并发程序,关键问题在于:在访问共享的可变状态时需要进行正确的管理.同步代码块和同步方法可以确保以原子的方式执行操作,同步还有另一个重要的方面:内存可见性. 可见性 为了确保多个线程之间对内存 ...

  5. java计算时间差_JAVA并发编程三大Bug源头(可见性、原子性、有序性),彻底弄懂...

    原创声明:本文转载自公众号[胖滚猪学编程]​ 某日,胖滚猪写的代码导致了一个生产bug,奋战到凌晨三点依旧没有解决问题.胖滚熊一看,只用了一个volatile就解决了.并告知胖滚猪,这是并发编程导致的 ...

  6. java volatile 原子性_Java并发编程之验证volatile不能保证原子性

    Java并发编程之验证volatile不能保证原子性 通过系列文章的学习,凯哥已经介绍了volatile的三大特性.1:保证可见性 2:不保证原子性 3:保证顺序.那么怎么来验证可见性呢?本文凯哥(凯 ...

  7. java cas机制_java并发编程中的CAS机制,你理解嘛?

    学习Java并发编程,CAS机制都是一个不得不掌握的知识点.这篇文章主要是从出现的原因再到原理进行一个解析.希望对你有所帮助. 一.为什么需要CAS机制? 为什么需要CAS机制呢?我们先从一个错误现象 ...

  8. JAVA并发编程实战——共享对象

    目录 思维导图 1. 可见性 1. 1 过期数据 1.2 锁和可见性 1.3 Volatile变量 2. 发布和逸出 2.1 安全构建实践 3. 线程封闭 3.1 栈限制 3.2 ThreadLoca ...

  9. java 线程工厂_Java并发编程:Java的四种线程池的使用,以及自定义线程工厂

    引言 通过前面的文章,我们学习了Executor框架中的核心类ThreadPoolExecutor ,对于线程池的核心调度机制有了一定的了解,并且成功使用ThreadPoolExecutor 创建了线 ...

最新文章

  1. Ubuntu中的minicom
  2. Docker + FastDFS + Spring Boot 一键式搭建分布式文件服务器
  3. ubuntu 终端批量复制文件_《卡死你3000》批量文件复制命令详解
  4. oracle 10g 用户管理笔记
  5. ???????????? no permissions的解决办法 解决网上方法行不通的问题
  6. iOS开发之ReplayKit框架学习
  7. 计算机图形与游戏技术,宾夕法尼亚大学计算机图形与游戏技术研究生Offer及录取要求...
  8. Redis集群监控RedisClusterManager
  9. 第九届(2018)蓝桥杯 山东省赛解题报告(题目+分析+代码)
  10. H5 中 bordercolorlight 属性的用法及作用
  11. Java关键字(六)——super
  12. 收藏|2021年浅谈多任务学习
  13. Java 接口,多态
  14. 使用FlashCS6制作cocos2d-x动作脚本的思路整理
  15. 人才测评技术与应用【1】
  16. (原创)分享一下最近搞的tiny210V2从nand启动支持(K9GAG08U0F).
  17. 新浪邮箱模拟登录java
  18. PDF文件电子签名怎么做?分享一个好用的签名工具
  19. 谷歌发现利用零日漏洞的攻击、黑客通过漏洞入侵红十字会|2月17日全球网络安全热点
  20. 云的新出路迷你云?轻松搭建私有云平台 转载7

热门文章

  1. js中对日期进行加减
  2. 数字化时代,CIO该如何理解数字能力
  3. JDK 11 马上就要来了!JDK 12 还会远吗?
  4. Swoole 自定义项目初始化事件处理的实现
  5. Mozilla计划向Firefox浏览器中添加违规警告
  6. zabbix2.4.5自带mysql监控
  7. Infortrend EonStor GS赢得 “年度最佳混合式存储”大奖
  8. Visual Studio下包含多项目的解决方案及项目间引用
  9. JavaScript强化教程——jQuery选择器
  10. [每天一个知识点]1-程序员的三大美德(1)