Java多线程之内存可见性——synchronized
来源:互联网 发布:淘宝网,挂烫机加热器 编辑:程序博客网 时间:2024/05/17 23:45
synchronized能够保证锁内操作的原子性(同步),并且也具备内存可见性的特性
JMM(java内存管理)关于synchronized的两条规定:
1) 线程解锁前,必须把共享变量的最新值刷新到主内存中
2) 线程加锁时,将清空工作内存中的共享变量的值,
从而使用共享变量时需要从主内存中重新读取最新的值(加锁解锁需要的都是同一把锁)
(ps.线程解锁前对共享变量的修改在下次加锁时对其他线程可见)
.
线程执行互斥代码的过程:
1.获得互斥锁
2.清空工作内存
3.从主内存拷贝变量的最新副本到工作内存
4.执行代码(可能代码会改变共享变量的值)
5.将更改后的共享变量的值刷新到主内存中
6.释放互斥锁
public class Demo { //共享变量 private boolean ready = false; private int result = 0; private int number = 1; //可以猜想一下,读写操作的步骤的顺序,result可能是6或者0 //写操作 public void write() { ready = true; //写操作第一步 number = 2; //写操作第二步 } //读操作 public void read() { if(ready) { //读操作第一步 result = number*3; //读操作第二步 } System.out.println("result的值为:"+result); } //内部线程类 private class ReadWriteThread extends Thread { //根据构造方法中传入的flag参数。确定线程执行读操作还是写操作 private boolean flag; public ReadWriteThread(boolean flag) { this.flag = flag; } public void run() { if(flag) { //构造方法中传入true,执行写操作 write(); } else { //构造方法中传入flase,执行读操作 read(); } } } public static void main(String args[]) { Demo demo = new Demo(); //启动线程执行写操作 demo.new ReadWriteThread(true).start(); //启动线程执行读操作 demo.new ReadWriteThread(false).start(); }}/*导致共享变量在线程间不可见的原因:1.线程的交叉执行2.重排序结合线程交叉执行3.共享变量更新后的值没有在工作内存与主内存之间及时更新*/
在读写操作方法加入synchronized关键字,使其变成安全的代码:
public synchronized void write() { ready = true; number = 2;}public synchronized void read() { if(ready) { result = number*3; } System.out.println("result的值为:"+result);}/*synchronized相当于加了一把锁,锁内部的代码在一段时间内只能由一个线程执行,除非释放锁synchronized其原子性,避免了线程的交叉执行的发生;由于已经避免了线程的交叉执行,所以无论锁内部怎么重排序,都不会对结果造成影响;synchronized其可见性的特性,可以避免共享变量未及时更新;*/
!还有一种特殊的情况,就是还未执行写操作,先执行读操作,
这种情况也是result为0,但是由于不是因为线程交叉执行而导致的,所以使用synchronized关键字没有作用
避免这种情况的话,可以使用sleep()使其休眠,代码如下:
//修改代码,休眠操作public static void main(String args[]) { Demo demo = new Demo(); //启动线程执行写操作 demo.new ReadWriteThread(true).start(); try { Thread.sleep(1000); } catch(InterruptedException e) { e.printStackTrace(); } //启动线程执行读操作 demo.new ReadWriteThread(false).start();}
0 0
- Java多线程之内存可见性——synchronized
- Java多线程之内存可见性——synchronized与volatile比较
- java多线程之内存可见性-synchronized、volatile
- java多线程之内存可见性-synchronized、volatile
- Java多线程之内存可见性——volatile
- Java多线程之内存可见性
- Java多线程之内存可见性
- JAVA多线程之内存可见性笔记
- Java多线程之内存可见性
- Java多线程之内存可见性
- Java多线程之内存可见性
- 浅谈java多线程之内存可见性
- Java多线程之内存可见性
- Java多线程之内存可见性
- Java多线程之内存可见性
- Java多线程之内存可见性
- java多线程之内存可见性
- 细说Java多线程之内存可见性
- 我自己常用的linux RPM安装包下载地址
- 基于Delta3D的walk运动模式实现
- 比较复数的大小(用C++的类实现)
- Asp.net值得收藏的三十多段实用代码
- Java事务的类型
- Java多线程之内存可见性——synchronized
- c语言的推箱子
- Netty学习之旅----ByteBuf内部结构与API学习
- 1001. A+B Format (20)
- 安卓图片的压缩,尺寸,质量,采样率和微信压缩
- redhat 6 使用centos源 yum安装
- 2017的开端,导入工程到AS需要修改的文件
- Smarty基本配置与使用
- Java多线程之内存可见性——volatile