java 线程数组_Java 数组线程间可见性问题
并发编程中通常使用 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 数组线程间可见性问题相关推荐
- java定时线程池_java 定时器线程池(ScheduledThreadPoolExecutor)的实现
前言 定时器线程池提供了定时执行任务的能力,即可以延迟执行,可以周期性执行.但定时器线程池也还是线程池,最底层实现还是ThreadPoolExecutor,可以参考我的另外一篇文章多线程–精通Thre ...
- java线程安全性_Java并发-线程安全性
1.什么是线程安全性? 在线程安全性的定义中,最核心的就是正确性.当多线程访问调用某个类时,线程之间不会出现错误的交互,不管运行时线程如何交替执行,并且在主调代码不需要任何同步或协同,这个类都能表现出 ...
- java 多线程池_Java ThreadPoolExecutor线程池 同时执行50个线程
最近项目上有个需求,需要从FTP服务器中下载大批量的数据文件,然后解析该数据文件进行入库,数据库为oracle,最后在通过web工程,以报表和图表的形式进行展现. 这些批量的数据文件为纯文本文件,每天 ...
- java 改装电动_java 数组
数组: 数组是同意变量的集合,不仅可以是基本数据类型,也可以是类的对象集合. 数组的缺点就是定长,不能随时扩张,所以一般是确定个数时用,不确定时一般用集合. 优点就是可以一下子定义多个相同类型的数据. ...
- java 添加等待时间_Java中线程等待特定时间的最有效方法 - java
我知道这个问题here,但是我有一个稍微不同的问题.如果我希望自己通过各种Thread方法(而不是通过实用程序类或Quartz)手动编码某个线程在特定时间的运行,那么最有效(就开销而言)进行编码. 我 ...
- java 线程管理_Java平台线程管理
简介 在计算机领域中,我们说的并发(concurrency)是指一些列任务的同时运行.如果一台电脑有多个处理器或者有一个多核处理器,这个同时性是真正意义上的并发:但是一台电脑只有一个单核处理器,这个同 ...
- java 线程百科_Java并发——线程介绍
前言: 互联网时代已经发展到了现在.从以前只考虑小流量到现在不得不去考虑高并发的问题.扯到了高并发的问题就要扯到线程的问题.你是否问过自己,你真正了解线程吗?还是你只知道一些其他博客里写的使用方法.下 ...
- java 后台线程作用_Java 后台线程介绍
packagecom.aaa.threaddemo;/** 一 Java后台线程? * 守护线程--也称"服务线程",他是后台线程, * 它有一个特性,即为用户线程 提供 公共服务 ...
- java多线程通信_Java多线程-线程通信
原标题:Java多线程-线程通信 通信的方式 要想实现多个线程之间的协同,如:线程执行先后顺序.获取某个线程执行的结果等等.涉及到线程之间的相互通信,分为下面四类: 文件共享 网络共享 共享变量 JD ...
最新文章
- 新浪微博的“独立”与互联网社区的“群居”
- 【跃迁之路】【448天】刻意练习系列207(2018.04.29)
- Cpp 对象模型探索 / 虚继承带虚函数的基类的子类的内存布局
- 电子测量与仪器第四版pdf_固定资产管理系统_资产分类名称(电子和通信测量分析仪器篇)...
- 关于OPENSSL的使用
- 嵌入式基础认识1:存储器(如RAM、ROM和FLASH)
- Tensorflow快餐教程(4) - 矩阵
- c语言指针化简带分数,c语言带分数四则运算问题!!!要求被调函数,化简.
- layui 图片展示添加一个x_Layx 演示示例
- [paper reading] CenterNet (Object as Points)
- node.js 学习书籍推荐
- 范型编程系列二(非原创)
- 区块链基础语言(二)——Go语言开发环境搭建
- 超简单的HIDPI设置
- Windows十四种系统故障解决方法
- 笔记本用HDMI转VGA转接线后,显示器没声音的解决方法
- 微服务注册中心怎么选?
- ps -mp pid -o THREAD,tid,time;printf %x\n tid;jstack pid |grep tid -A 30;CPU占用太高追查
- 如何利用 Python + Selenium 自动化快速截图
- 有趣的CSS实现“勾号”
热门文章
- python 文件读写找不到文件-python之文件读写
- python少儿编程 在线课程-宁波Python程序开发课程
- python可以做什么系统-python能做哪方面的工作
- python将数字转变为中文读法-Python实现把数字转换成中文
- python中可以用中文作为变量-在Python 3.x中可以使用中文作为变量名。
- python调用shell命令-python中执行shell命令的几个方法小结
- python编程培训-什么是Python?老男孩Python编程培训
- python怎么识别拼音-python获取一组汉字拼音首字母的方法
- spring中的bean创建
- mybatis中的TypeHandler设计与实现