JDK中Concurrent包介绍及使用(包含atomic包/lock包/并发容器/执行器)
Java Concurrent并发包概括 https://blog.csdn.net/u012232736/article/details/79919450
Java中的Atomic包使用指南 http://ifeve.com/java-atomic/
深入解析Java AtomicInteger 原子类型 https://www.cnblogs.com/rever/p/8215743.html
Java 并发工具包 java.util.concurrent 用户指南 https://blog.csdn.net/defonds/article/details/44021605/
0x15Java引用赋值,是原子操作吗? 线程安全吗?
Q1 什么是原子操作
所谓原子操作,就是该操作绝不会在执行完毕前被任何其他任务或事件打断,也就说,它的最小的执行单位,不可能有比它更小的执行单位,因此这里的原子实际是使用了物理学里的物质微粒的概念。
Q2 非原子的64位操作
这是一个局部的概念,大多地方我们遇不到这样的说法
当线程在没有同步的情况下读取变量时,可能会得到一个失效值,但至少这个值是由之前某个线程设置的值,而不是一个随机值。这种安全性保证也被称为最低安全性( out-of-thin-air safety)。
最低安全性适用于绝大多数变量,但是存在一个例外:非volatile 类型的64位数值变量(double和long,请参见3.1.4节)。Java内存模型要求,变量的读取操作和写入操作都必须是原子操作,但对于非volatile类型的long和double变量,JVM允许将64位的读操作或写操作分解为两个32位的操作。当读取一个非volatile类型的long变量时,如果对该变量的读操作和写操作在不同的线程中执行,那么很可能会读取到某个值的高32位和另一个值的低32位。因此,即使不考虑失效数据问题,在多线程程序中使用共享且可变的long和double等类型的变量也是不安全的,除非用关键字volatile来声明它们,或者用锁保护起来。
Q3 Java中 有哪些数据类型,它们分别占用的空间大小是多少
一、基本数据类型:
byte:Java中最小的数据类型,在内存中占8位(bit),即1个字节,取值范围-128~127,默认值0
short:短整型,在内存中占16位,即2个字节,取值范围-32768~32717,默认值0
int:整型,用于存储整数,在内在中占32位,即4个字节,取值范围-2147483648~2147483647,默认值0
long:长整型,在内存中占64位,即8个字节-263~263-1,默认值0L
float:浮点型,在内存中占32位,即4个字节,用于存储带小数点的数字(与double的区别在于float类型有效小数点只有6~7位),默认值0
double:双精度浮点型,用于存储带有小数点的数字,在内存中占64位,即8个字节,默认值0
char:字符型,用于存储单个字符,占16位,即2个字节,取值范围0~65535,默认值为空
boolean:布尔类型,占1个字节,用于判断真或假(仅有两个值,即true、false),默认值false
二、引用数据类型:
类、接口类型、数组类型、枚举类型、注解类型。
区别:
基本数据类型在被创建时,在栈上给其划分一块内存,将数值直接存储在栈上。
引用数据类型在被创建时,首先要在栈上给其引用(句柄)分配一块内存,而对象的具体信息都存储在堆内存上,然后由栈上面的引用指向堆中对象的地址。
例如,有一个类Person,有属性name,age,带有参的构造方法,
Person p = new Person("zhangsan",20);
在内存中的具体创建过程是:
1.首先在栈内存中位其p分配一块空间;
2.在堆内存中为Person对象分配一块空间,并为其三个属性设初值"",0;
3.根据类Person中对属性的定义,为该对象的两个属性进行赋值操作;
4.调用构造方法,为两个属性赋值为"Tom",20;(注意这个时候p与Person对象之间还没有建立联系);
5.将Person对象在堆内存中的地址,赋值给栈中的p;通过引用(句柄)p可以找到堆中对象的具体信息。
相关知识:
静态区: 保存自动全局变量和 static 变量(包括 static 全局和局部变量)。静态区的内容在总个程序的生命周期内都存在,由编译器在编译的时候分配。
堆区: 一般由程序员分配释放,由 malloc 系列函数或 new 操作符分配的内存,其生命周期由 free 或 delete 决定。在没有释放之前一直存在,直到程序结束,由OS释放。其特点是使用灵活,空间比较大,但容易出错
栈区: 由编译器自动分配释放,保存局部变量,栈上的内容只在函数的范围内存在,当函数运行结束,这些内容也会自动被销毁,其特点是效率高,但空间大小有限
文字常量区(在方法区内部): 常量字符串就是放在这里的。 程序结束后由系统释放。
Q4 有哪些操作是原子操作
有一些操作比如 int 变量的赋值,引用对象的赋值,
这些的开销很小,甚至我们似乎可以把他们理解为原子性的操作。它们在某些平台是原子性的。
但最后的结论应是:
除非代码所工作的操作系统平台环境或者java官方指定这个操作是原子性操作,线程安全的。我们不应该把它当做原子性的操作,线程安全性的操作。
那么引用进行赋值不是线程安全的,不是原子性的。至少java没有这样答应我们,因为它提供了原子操作类
JDK1.5之后的java.util.concurrent.atomic包里,多了一批原子处理类。
- 标量类:AtomicBoolean,AtomicInteger,AtomicLong,AtomicReference
- 数组类:AtomicIntegerArray,AtomicLongArray,AtomicReferenceArray
- 更新器类:AtomicLongFieldUpdater,AtomicIntegerFieldUpdater,AtomicReferenceFieldUpdater
- 复合变量类:AtomicMarkableReference,AtomicStampedReference
AtomicBoolean,AtomicInteger,AtomicLong,AtomicReference这四种基本类型用来处理布尔,整数,长整数,对象四种数据,其内部实现不是简单的使用synchronized,而是一个更为高效的方式CAS
(compare and swap) + volatile和native方法,从而避免了synchronized的高开销,执行效率大为提升。
结论
其实发现是自己跟自己挖了一个坑,答案很简单。
除非代码所工作的操作系统平台环境或者java官方指定这个操作是原子性操作,线程安全的。我们不应该把它当做原子性的操作,线程安全性的操作。
基于CAS的线程安全机制很好很高效,但要说的是,并非所有线程安全都可以用这样的方法来实现,这只适合一些粒度比较小,例如计数器这样的需求用起来才有效。
作者:夏大王2019
链接:https://www.jianshu.com/p/4e6d4da1434a
來源:简书
简书著作权归作者所有,任何形式的转载都请联系作者获得授权并注明出处。
JDK中Concurrent包介绍及使用(包含atomic包/lock包/并发容器/执行器)的更多相关文章
- IDEA 构建为了打 jar 包的工程,包含 maven 打 jar 包的过程
前言:最近自己写了一个单表查询的组件,包含前端.后台,所以需要向阿里的 druid 一样将所有文件打到一个 jar 包里,这里首先记录如何打 jar 包. 附:自己的一个 jar 包源码 https: ...
- JDK中的Atomic包中的类及使用
引言 Java从JDK1.5开始提供了java.util.concurrent.atomic包,方便程序员在多线程环境下,无锁的进行原子操作.原子变量的底层使用了处理器提供的原子指令,但是不同的CPU ...
- 冷饭新炒:理解JDK中UUID的底层实现
前提 UUID是Universally Unique IDentifier的缩写,翻译为通用唯一标识符或者全局唯一标识符.对于UUID的描述,下面摘录一下规范文件A Universally Uniqu ...
- JDK中所包含的设计模式
本文主要是归纳了JDK中所包含的设计模式,包括作用和其设计类图.首先来个总结,具体的某个模式可以一个一个慢慢写,希望能对研究JDK和设计模式有所帮助. 一.设计模式是什么(1)反复出现问题的解决方案( ...
- B8 Concurrent JDK中的乐观锁与原子类
[概述] 乐观锁采用的是一种无锁的思想,总是假设最好的情况,认为一个事务在读取数据的时候,不会有别的事务对数据进行修改,只需要在修改数据的时候判断原数据数据是否已经被修改了.JDK 中 java.ut ...
- 【Javac编译异常】javac编译提示jdk中的包找不到的问题error: package jdk.internal.org.objectweb.asm does not exist 和 error: cannot find symbol
一.复现步骤 1)编写待编译的java类 package f_asm_and_javassist; import jdk.internal.org.objectweb.asm.*; import ja ...
- 列出JDK中常用的Java包
列出JDK中常用的Java包 1.java.lang 2.java.sql 3.java.io 4.java.math 5.java.text 6.java.net 7.java.util 8.jav ...
- 曹工力荐:调试 jdk 中 rt.jar 包部分的源码(可自由增加注释,修改代码并debug)
背景 大家知道,jdk安装的目录下,一般会有个src.zip包,这个包基本对应了rt.jar这个包.rt.jar这个包里面,就放了jdk中,jdk采用java实现的那部分类库代码,比如java.lan ...
- celery介绍、架构、快速使用、包结构,celery执行异步、延迟、定时任务,django中使用celery,定时更新首页轮播图效果实现,数据加入redis缓存的坑及解决
今日内容概要 celery介绍,架构 celery 快速使用 celery包结构 celery执行异步任务 celery执行延迟任务 celery执行定时任务 django中使用celery 定时更新 ...
随机推荐
- WORD2010如何把全角字母和数字批量转换成半角
个人觉得全角字符看起来相当别扭,如果文档中存在大量全角形式的字母和数字,要如何把它们全部转化成半角的呢? 全角和半角 全角是指一个字符占用两个标准字符位置的状态.汉字字符和规定了全角的英文字符 ...
- 5.django学习模型
##Django Models ##编写models 1.在应用根目录下创建models.py并引入models模块,创建类,继承models.Model该类即是一张数据表 2.字段创建 ##映射数据 ...
- 使用WinPcap(SharpPcap)实现ARP抓包以实现设备IP搜索功能
在监控摄像机安装后,往往需要设置IP等信息,在IP不知道的情况下,IP搜索是一个很常见也必须的功能. 考虑到设备IP和当前局域网可能不在同一个网段,ARP是一个不错的选择. 首先安装WinPcap软件 ...
- 【简单易用的傻瓜式图标设计工具】Logoist 3.1 for Mac
[简介] Logoist 是一款Mac上强大易用的傻瓜式图标设计制作工具,通过使用内置模板和预设效果,您可以立即创建高质量的图形内容和艺术作品.通过使用该应用程序,可用于制作图标LOGO. 一款用于创 ...
- bzoj2733 离线+并查集+主席树
https://www.lydsy.com/JudgeOnline/problem.php?id=2733 网上清一色的合并线段树题解,我又不会,只能自己胡来,没想到Rush过去了 永无乡包含 n 座 ...
- 2017-12-15python全栈9期第二天第四节之格式化输出%s和用户交互个人简历模板
#!/user/bin/python# -*- coding:utf-8 -*-name = input('姓名:')age = input('年龄:')job = input('工作:')hobbi ...
- shipyard 管理swarm集群(附etcd发现服务方法)
docker swarm集群 第一步:安装swarm集群 192.168.132.131----->(manger1,node) 192.168.132.132----->(manger2 ...
- CSS-Naming-Conventions--BEM
BEM BEM : Block Element Modifier There are only two hard problems in Computer Sciences:cache invalid ...
- spring boot @Value Could not resolve placeholder
@Configuration public class PropertySourcePlaceholderConfig { @Bean public PropertySourcesPlaceholde ...
- Linux 命令详解(十二)Systemd 入门教程:使用定时器发送邮件(mail)
Systemd 定时器教程:http://www.ruanyifeng.com/blog/2018/03/systemd-timer.html 一.定时任务 Systemd 定时任务:每小时发送一封电 ...