并发编程中通常使用 volatile 保证线程间可见性,但是被 volatile 修饰的数组中元素是无法保证线程间可见的,例如 ConcurrentHashMap 对这一问题采用 Unsafe 的方式访问 U.getObjectVolatile(tab, ((long)i << ASHIFT) + ABASE);

关于 volatile 示例

暂无关于 volatile array 失败测试用例

解释

在 Java 中无论是基础类型数组还是对象类型数组底层都是一个对象,区别是数组对象在对象头中多出 32 位数组长度标识。

普通对象需要保证线程间可见通常修饰 volatile 关键字,若对象内成员未修饰 volatile 关键字,成员是无法保证线程间可见的。在初始化数组或者创建数组是无法为元素修饰 volatile 关键字的,同样的解释还有:

这个是因为Java数组在元素层面的元数据设计上的缺失,无法表达元素是final、volatile等语义,所以开了后门,使用getObjectVolatile用来补上无法表达元素是volatile的坑,@Stable用来补上final的坑,数组元素就跟没有标volatile的成员字段一样,无法保证线程之间可见性。

链接:https://www.jianshu.com/p/5808db3e2ace

保证数组元素可见性的几种方式

Unsafe.getVolatileObject

public class VolatileArray {

private volatile Object[] nums = new Object[]{new Object()};

private static Unsafe U;

private static long NUMS;

static {

try {

Class> clazz = Class.forName("sun.misc.Unsafe");

Field theUnsafe = clazz.getDeclaredField("theUnsafe");

theUnsafe.setAccessible(true);

U = (Unsafe) theUnsafe.get(null);

NUMS = U.objectFieldOffset(VolatileArray.class.getDeclaredField("nums"));

} catch (ClassNotFoundException | NoSuchFieldException | IllegalAccessException e) {

e.printStackTrace();

}

}

public static void main(String[] args) throws InterruptedException {

VolatileArray example = new VolatileArray();

new Thread(() -> {

try {

TimeUnit.MILLISECONDS.sleep(200);

} catch (InterruptedException e) {

e.printStackTrace();

}

example.nums[0] = new Object();

}).start();

new Thread(() -> {

while (true) {

Object[] objects = (Object[]) U.getObjectVolatile(example, NUMS);

if (objects[0] != null) {

System.out.println("index updated");

break;

}

}

}).start();

}

}

AtomicReferenceArray

public class VolatileArray {

private AtomicReferenceArray atomicReferenceArray = new AtomicReferenceArray<>(1);

public static void main(String[] args) throws InterruptedException {

VolatileArray example = new VolatileArray();

new Thread(() -> {

try {

TimeUnit.MILLISECONDS.sleep(200);

} catch (InterruptedException e) {

e.printStackTrace();

}

example.atomicReferenceArray.set(0, new Object());

}).start();

new Thread(() -> {

while (true) {

if (example.atomicReferenceArray.get(0) != null) {

System.out.println("index updated");

break;

}

}

}).start();

}

}

AtomicReferenceArray 实现与上方 Unsafe 代码思想基本一致。

java 线程数组_Java 数组线程间可见性问题相关推荐

  1. java定时线程池_java 定时器线程池(ScheduledThreadPoolExecutor)的实现

    前言 定时器线程池提供了定时执行任务的能力,即可以延迟执行,可以周期性执行.但定时器线程池也还是线程池,最底层实现还是ThreadPoolExecutor,可以参考我的另外一篇文章多线程–精通Thre ...

  2. java线程安全性_Java并发-线程安全性

    1.什么是线程安全性? 在线程安全性的定义中,最核心的就是正确性.当多线程访问调用某个类时,线程之间不会出现错误的交互,不管运行时线程如何交替执行,并且在主调代码不需要任何同步或协同,这个类都能表现出 ...

  3. java 多线程池_Java ThreadPoolExecutor线程池 同时执行50个线程

    最近项目上有个需求,需要从FTP服务器中下载大批量的数据文件,然后解析该数据文件进行入库,数据库为oracle,最后在通过web工程,以报表和图表的形式进行展现. 这些批量的数据文件为纯文本文件,每天 ...

  4. java 改装电动_java 数组

    数组: 数组是同意变量的集合,不仅可以是基本数据类型,也可以是类的对象集合. 数组的缺点就是定长,不能随时扩张,所以一般是确定个数时用,不确定时一般用集合. 优点就是可以一下子定义多个相同类型的数据. ...

  5. java 添加等待时间_Java中线程等待特定时间的最有效方法 - java

    我知道这个问题here,但是我有一个稍微不同的问题.如果我希望自己通过各种Thread方法(而不是通过实用程序类或Quartz)手动编码某个线程在特定时间的运行,那么最有效(就开销而言)进行编码. 我 ...

  6. java 线程管理_Java平台线程管理

    简介 在计算机领域中,我们说的并发(concurrency)是指一些列任务的同时运行.如果一台电脑有多个处理器或者有一个多核处理器,这个同时性是真正意义上的并发:但是一台电脑只有一个单核处理器,这个同 ...

  7. java 线程百科_Java并发——线程介绍

    前言: 互联网时代已经发展到了现在.从以前只考虑小流量到现在不得不去考虑高并发的问题.扯到了高并发的问题就要扯到线程的问题.你是否问过自己,你真正了解线程吗?还是你只知道一些其他博客里写的使用方法.下 ...

  8. java 后台线程作用_Java 后台线程介绍

    packagecom.aaa.threaddemo;/** 一 Java后台线程? * 守护线程--也称"服务线程",他是后台线程, * 它有一个特性,即为用户线程 提供 公共服务 ...

  9. java多线程通信_Java多线程-线程通信

    原标题:Java多线程-线程通信 通信的方式 要想实现多个线程之间的协同,如:线程执行先后顺序.获取某个线程执行的结果等等.涉及到线程之间的相互通信,分为下面四类: 文件共享 网络共享 共享变量 JD ...

最新文章

  1. 新浪微博的“独立”与互联网社区的“群居”
  2. 【跃迁之路】【448天】刻意练习系列207(2018.04.29)
  3. Cpp 对象模型探索 / 虚继承带虚函数的基类的子类的内存布局
  4. 电子测量与仪器第四版pdf_固定资产管理系统_资产分类名称(电子和通信测量分析仪器篇)...
  5. 关于OPENSSL的使用
  6. 嵌入式基础认识1:存储器(如RAM、ROM和FLASH)
  7. Tensorflow快餐教程(4) - 矩阵
  8. c语言指针化简带分数,c语言带分数四则运算问题!!!要求被调函数,化简.
  9. layui 图片展示添加一个x_Layx 演示示例
  10. [paper reading] CenterNet (Object as Points)
  11. node.js 学习书籍推荐
  12. 范型编程系列二(非原创)
  13. 区块链基础语言(二)——Go语言开发环境搭建
  14. 超简单的HIDPI设置
  15. Windows十四种系统故障解决方法
  16. 笔记本用HDMI转VGA转接线后,显示器没声音的解决方法
  17. 微服务注册中心怎么选?
  18. ps -mp pid -o THREAD,tid,time;printf %x\n tid;jstack pid |grep tid -A 30;CPU占用太高追查
  19. 如何利用 Python + Selenium 自动化快速截图
  20. 有趣的CSS实现“勾号”

热门文章

  1. python 文件读写找不到文件-python之文件读写
  2. python少儿编程 在线课程-宁波Python程序开发课程
  3. python可以做什么系统-python能做哪方面的工作
  4. python将数字转变为中文读法-Python实现把数字转换成中文
  5. python中可以用中文作为变量-在Python 3.x中可以使用中文作为变量名。
  6. python调用shell命令-python中执行shell命令的几个方法小结
  7. python编程培训-什么是Python?老男孩Python编程培训
  8. python怎么识别拼音-python获取一组汉字拼音首字母的方法
  9. spring中的bean创建
  10. mybatis中的TypeHandler设计与实现