java的线程安全

来源:互联网 发布:樱井知香2017作品番号 编辑:程序博客网 时间:2024/05/17 06:23
可见性:一个线程对共享变量值的修改,能够及时地被其他线程看到。


共性变量:如果一个变量在多个线程的工作内存中都存在副本,那么这个变量就是这几个线程的共享变量。


Java内存模型(JMM):描述了Java程序中各种变量(线程共享变量)的访问规则,以及在JVM中将变量存储到内存和从内存中读取出来变量的底层细节。


所有的变量都存储在主内存中,每个线程都有自己独立的工作内存,里面保存改线程使用到的变量的副本(住内存在改变量的一份拷贝)


线程对共享变量的所有操作都必须在自己的工作内存中进行,不能直接从主内存中读写;不同线程之间无法直接访问其他线程工作内存中的变量,线程间变量值的传递需要通过主内存来完成。


要实现共享变量的可见性,必须保证两点:
1.线程修改后的共享变量值能够及时从工作内存刷新到主内存中
2.其他线程能够及时把共享变量的最新值从朱内存更新到自己的工作内存中


Java语言层面支持的可见性实现方式:
1.synchronized实现可见性,互斥锁,原子性(同步),可见性
2.volatile,可见性,但无原子性

重排序:代码书写的顺序与实际执行的顺序不同,指令重排序是编译器或处理器为了提高程序性能而坐的优化
1.编译器优化的重排序(编译器优化)
2.指令级并行重排序(处理器优化)
3.内存系统的重排序(处理器优化)

as-if-serial:无论如何重排序,程序执行的结果应该与代码顺序执行的结果一致(Java编译器、运行和处理器都会保证Java爱单线程下遵循ad-if-serial语义)


重排序不会给单线程带来可见性问题;多线程中程序交错执行时,重排序可能会造成内存可见性问题。




导致共享变量在线程间表空间的原因:
1.线程的交错执行
2.重排序结合线程交叉执行
3.共享变量更新后的值没有在构造内存与主内存间及时更新

volatile实现可见性
通过加入内存屏障和禁止重排序优化来实现的
、对volatile变量执行写操作是,会在写操作前加入一条store屏蔽指令
、多volatile变量执行读操作是,会在读操作前加入一条load屏障指令
通俗来讲,volatile变量在每次被线程访问时,都强迫从主内存中重读该变量的值,儿当该变量发生变化时,又强迫线程将最新的值刷新到
主内存。这样任何时刻,不同的线程总能看到该变量的最新值。


volatile使用 场合
1.对变量的写入操作不依赖其当前值
、不满足:num++,cnt*=5;
、满足:boolean 变量、记录温度变化的变量等
2.该变量没有包含在具有其他变量的不变式中
、不满足:不变式low<up

synchronized和volatile比较
、volatile不需要加锁,比synchonized更轻量级,不会阻塞线程
、从内存可见性角度讲,volatile读相当于加锁,volatile写相当于解锁
、synchonized既能保证可见性,又能保证原子性,而volatile只能保证可见性,无法保证原子性


要注意----对double,long变量的读写可能不是原子性的,java内存模型允许JMM将没有被volatile修饰的64位数据类型的读写操作
划分为两次32位的读写操作来进行


0 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 河南水利五大员怎么办 转学学校没学位怎么办 koa2 渲染网页慢怎么办 烤箱的灯不亮了怎么办 兰州新区非农户怎么办? 施工员证书到期怎么办 银行从业过期了怎么办 国地税合并协税员怎么办 快递员虚报重量怎么办 信用卡刷整数了怎么办 汽车年检尾气不合格怎么办 车辆年检尾气不合格怎么办 年检手刹不合格怎么办 社会保障卡怎么办郑州的 网约车驾驶员证怎么办 干洗出现问题了怎么办 教师工资太低了怎么办 鸽子得了新城疫怎么办 氮肥施多了怎么办 当兵体质差跑步怎么办 手盘核桃脏了怎么办 怀孕吃了巴旦木怎么办 护士证丢了怎么办 扶贫搬迁老房子怎么办 ucl录取差两分怎么办 考研准考证号填错了怎么办? 拿到工伤证后怎么办 专接本有挂科怎么办 小孩发烧后惊厥怎么办 深圳民办学校停办学生怎么办 教育机构不退钱怎么办 智慧树错过选课怎么办 河南城建学院怎么办网 建学校土地手续怎么办 德国预科不能毕业怎么办 想出国打工怎么办手续 终结执行了该怎么办 网银界面打不开怎么办 abr检查结果异常怎么办 大排畸胎儿位置不好怎么办 交社保中途死了怎么办