可见性是一种复杂的属性,因为可见性中的错误总是会违背我们的直觉。在单线程环境中,如果向某个变量先写入值,然后在没有其他写入操作的情况下读取这个变量,那么总能得到相同的值。这看起来很自然。 然而,当读操作和写操作在不同的线程中执行时,情况却并非如此。

public class NoVisiaility {

private static boolean ready;

private static int number;

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;

}

}

在上面程序中,主线程和读线程都访问共享变量ready和number。主线程启动读线程,然后将number设为42,并将ready设为true。读线程一直循环直到发现ready的值变为true,然后输出number的值。虽然NoVisiaility看起来会输出42,但事实上很可能输出0,或根本无法终止。这是因为在代码中没有使用足够的同步机制,因此无法保证主线程写入的ready值和number值对于读线程来说是可见的。

NoVisiaility可能会持续循环下去,因为读线程可能永远都看不到ready的值。一种更奇怪的现象时,NoVisiaility可能会输出0,因为读线程可能看到了写入ready的值,但却没有看到之后写入number的值,这种现象被称为“重排序(Reorderiing)”。只要在某个线程中无法检测到重排序情况(即使在其他线程中可以很明显地看到该线程中的重排序),那么就无法确保线程中的操作将按照程序中指定的顺序来执行。当主线程手写如number,然后在没有同步的情况下写入ready,那么读线程看到的顺序可能与写入的顺序完全相反。          在没有同步的情况下,编译器、处理器以及运行时等都可能对操作的执行顺序进行一些意想不到调整。在缺乏足够同步的多线程程序中,要想对内存操作的执行顺序进行判断,几乎无法得到正确的结论。

一种简单的方法能够避免这些复杂的问题:只要有数据在多个线程之间共享,就使用正确的同步。

java 变量的线程可见性_Java多线程——变量可见性相关推荐

  1. java 两个线程同步_Java 多线程(二)—— 线程的同步

    实现Runnable接口 public classTestThread2 {public static voidmain(String [] args){ Window window=newWindo ...

  2. java 线程 组成_java多线程

    一:基本知识点 1.1线程与进程区别: 1.进程是资源分配的最小单位,线程是CPU调度的最小单位 2.一个进程由一个或多个线程组成 3.进程之间相互独立,每个进程都有独立的代码和数据空间,但同一进程下 ...

  3. java 多线程变量可见性_Java多线程:易变变量,事前关联和内存一致性

    java 多线程变量可见性 什么是volatile变量? volatile是Java中的关键字. 您不能将其用作变量或方法名称. 期. 我们什么时候应该使用它? 哈哈,对不起,没办法. 当我们在多线程 ...

  4. java 线程由浅入深_Java多线程:由浅入深看synchronized的底层实现原理

    Java多线程:由浅入深看synchronized的底层实现原理-1.jpg (91.72 KB, 下载次数: 0) 2018-9-21 03:55 上传 前言 前俩篇文章,我们聊了聊线程/进程的概念 ...

  5. java线程入门_java多线程快速入门(一)

    1.什么是进程 比如:QQ.QQ游戏.eclipse都是进程,可以通过任务管理器查看进程 2.进程和线程区别 线程是进程的一部分,一个进程可以包含多个线程,一个线程只能属于一个进程 进程是所有线程的集 ...

  6. java线程 锁_Java多线程(二) 多线程的锁机制

    当两条线程同时访问一个类的时候,可能会带来一些问题.并发线程重入可能会带来内存泄漏.程序不可控等等.不管是线程间的通讯还是线程共享数据都需要使用Java的锁机制控制并发代码产生的问题.本篇总结主要著名 ...

  7. java中什么是线程安全_Java 多线程:什么是线程安全性

    线程安全性 什么是线程安全性 <Java Concurrency In Practice>一书的作者 Brian Goetz 是这样描述"线程安全"的:"当多 ...

  8. java线程池_Java多线程并发:线程基本方法+线程池原理+阻塞队列原理技术分享...

    线程基本方法有哪些? 线程相关的基本方法有 wait,notify,notifyAll,sleep,join,yield 等. 线程等待(wait) 调用该方法的线程进入 WAITING 状态,只有等 ...

  9. java环境变量path好长_java环境变量设置

    java环境变量设置 环境变量是一个具有特定名字的对象,它包含了一个或者多个应用程序所将使用到的信息.例如path,当要求系统运行一个程序而没有告诉它程序所在的完整路径时,系统除了在当前目录下面寻找此 ...

最新文章

  1. Color Blended Layers
  2. SQL Server 2008数据库,显示正在恢复,想把它删了结果删除不了
  3. Angularjs实现下拉框自动匹配键值对对象技巧
  4. matlab将struct和cell转换成matrices
  5. 9206-1121-对象数组
  6. C语言数组查找(线性查找 折半查找)
  7. opencv 凸包讲解和绘制
  8. 开源日志系统log4cplus(五)
  9. asp.net 安全
  10. Qt QDebug 打印自定义结构体
  11. 2022新版千月影视双端APP带H5功能开源程序支持当面付和易支付
  12. 国二c语言南开版的机试100题,[互联网]免费ncre全国计算机等级考试二级c语言上机---南开100题答案...
  13. PCB生产工艺流程博大精深
  14. 东芝服务器报错误代码维修,东芝复印机维修故障代码
  15. ArcHydroTools 10.5版本的安装与使用(附下载链接与教程)
  16. oracle mysql迁移方案_Oracle/云MySQL/MsSQL“大迁移”真相及最优方案
  17. web开发详解,学习web前端开发的网站
  18. 学生成绩处理(函数版)
  19. 解决blur与click冲突
  20. 软件设计模式-门面设计模式

热门文章

  1. STL库(C++11)提供的异步执行方法的方式
  2. 正则表达式(括号)、[中括号]、{大括号}的区别小结
  3. pytorch.range() 和 pytorch.arange() 的区别
  4. Tensorflow中tf.ConfigProto()详解
  5. Python标准库——collections模块的Counter类
  6. LeetCode简单题之子数组最大平均数 I
  7. 2021年华为与小康-北汽-长安
  8. 基于区域的CNN(R-CNN)
  9. 2021年大数据Spark(二十七):SparkSQL案例一花式查询和案例二WordCount
  10. TypeError: ord() expected a character, but string of length 6 found