synchronized的规定

  • 线程解锁前,必须把共享变量刷新到主内存
  • 线程加锁前将清空工作内存共享变量的值,需要从主存中获取共享变量的值。

加锁(synchronized 同步)的功能不仅仅局限于互斥行为,同时还存在另外一个重要的方面:内存可见性。我们不仅希望防止某个线程正在使用对象状态而另一个线程在同时修改该状态,而且还希望确保当一个线程修改了对象状态后,其他线程能够看到该变化。而线程的同步恰恰也能够实现这一点。

内置锁可以用于确保某个线程以一种可预测的方式来查看另一个线程的执行结果。为了确保所有的线程都能看到共享变量的最新值,可以在所有执行读操作或写操作的线程上加上同一把锁。下图示例了同步的可见性保证。

当线程 A 执行某个同步代码块时,线程 B 随后进入由同一个锁保护的同步代码块,这种情况下可以保证,当锁被释放前,A 看到的所有变量值(锁释放前,A 看到的变量包括 y 和 x)在 B 获得同一个锁后同样可以由 B 看到。换句话说,当线程 B 执行由锁保护的同步代码块时,可以看到线程 A 之前在同一个锁保护的同步代码块中的所有操作结果。如果在线程 A unlock M 之后,线程 B 才进入 lock M,那么线程 B 都可以看到线程 A unlock M 之前的操作,可以得到 i=1,j=1。如果在线程 B unlock M 之后,线程 A 才进入 lock M,那么线程 B 就不一定能看到线程 A 中的操作,因此 j 的值就不一定是 1。

synchronized线程可见性安全案例

package com.keytech.task;import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;public class SynchronizedTestOne {public static void main(String[] args) {ExecutorService executorService = Executors.newCachedThreadPool();Rumenzz r=new Rumenzz();//线程1executorService.execute(()->{r.setAge(200);});//线程2executorService.execute(()->{System.out.println(r.getAge());});executorService.shutdown();}
}class Rumenzz{private Integer age=0;public synchronized Integer getAge() {return age;}public synchronized void setAge(Integer age) {this.age = age;}
}

以上代码是线程安全的,输出0200,因为线程1和线程2的执行顺序不一样。为了保证结果的一致性,需要控制线程的执行顺序。

package com.keytech.task;import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;/*** @className: SynchronizedTestOne* @description: TODO 类描述* @author: mac* @date: 2021/1/1**/
public class SynchronizedTestOne {public static void main(String[] args) {ExecutorService executorService = Executors.newCachedThreadPool();Rumenzz r=new Rumenzz();CountDownLatch c=new CountDownLatch(1);executorService.execute(()->{try {c.await();} catch (InterruptedException e) {e.printStackTrace();}System.out.println(r.getAge());});executorService.execute(()->{try {Thread.sleep(5000);c.countDown();} catch (InterruptedException e) {e.printStackTrace();}r.setAge(200);});//关闭线程池executorService.shutdown();}
}class Rumenzz{private Integer age=0;public synchronized Integer getAge() {return age;}public synchronized void setAge(Integer age) {this.age = age;}
}

线程安全输出200

多线程之线程可见性synchronized相关推荐

  1. java多线程:线程同步synchronized(不同步的问题、队列与锁),死锁的产生和解决

    0.不同步的问题 并发的线程不安全问题: 多个线程同时操作同一个对象,如果控制不好,就会产生问题,叫做线程不安全. 我们来看三个比较经典的案例来说明线程不安全的问题. 0.1 订票问题 例如前面说过的 ...

  2. 并发编程-06线程安全性之可见性 (synchronized + volatile)

    文章目录 线程安全性文章索引 脑图 可见性定义 导致不可见的原因 可见性 -synchronized (既保证原子性又保证可见性) 可见性 - volatile(但不保证操作的原子性) volatil ...

  3. java 线程由浅入深_Java多线程:由浅入深看synchronized的底层实现原理

    Java多线程:由浅入深看synchronized的底层实现原理-1.jpg (91.72 KB, 下载次数: 0) 2018-9-21 03:55 上传 前言 前俩篇文章,我们聊了聊线程/进程的概念 ...

  4. 处理java多线程时线程安全问题 - ThreadLocal和Synchronized

    多线程在自动化测试中用的不多,也就是说我们用单线程可以完成大部分的自动化测试脚本. 主要有两个原因,首先是因为自动化测试首要考虑的是脚本的稳定性,所以一般会牺牲效率以保证脚本稳定,其次是由于局限于我们 ...

  5. JavaSE学习53:细说多线程之内存可见性

    一共享变量在线程间的可见性 (1)有关可见性的一些概念介绍 可见性:一个线程对共享变量值的修改,能够及实地被其他线程看到. 共享变量:如果一个变量在多个线程的工作内存中都存在副本,那么这个变量就是这几 ...

  6. Java线程(二):线程同步synchronized和volatile

    上篇通 过一个简单的例子说明了线程安全与不安全,在例子中不安全的情况下输出的结果恰好是逐个递增的(其实是巧合,多运行几次,会产生不同的输出结果),为什么 会产生这样的结果呢,因为建立的Count对象是 ...

  7. java synchronized块_Java多线程同步代码块Synchronized

    Java多线程同步代码块Synchronized Java中的每个对象都有一个与之关联的内部锁(Intrinsic lock). 这种锁也称为监视器(Monitor), 这种内部锁是一种排他锁,可以保 ...

  8. java不同进程的相互唤醒_JAVA多线程之线程间的通信方式

    一,介绍 本总结我对于JAVA多线程中线程之间的通信方式的理解,主要以代码结合文字的方式来讨论线程间的通信,故摘抄了书中的一些示例代码. 二,线程间的通信方式 ①同步 这里讲的同步是指多个线程通过sy ...

  9. 单核CPU是否有线程可见性问题?

    本文仅是本人对问题的思考记录,并没有实操验证,有误请大家评论指出. 今天见到了一个经典的问题,单核CPU是否有线程可见性问题,学完操作系统应该可以直接回答,不会有线程安全问题.但如果结合JVM虚拟机来 ...

最新文章

  1. 天池NLP中文预训练模型赛来了!
  2. c++ 使用 math库笔记
  3. rocketmq还要eventbus_ListEventBuses_ListEventBuses_事件总线_C# SDK_阿里云SDK参考_事件总线EventBridge - 阿里云...
  4. 数据结构实验之图论八:欧拉回路
  5. 微信支付H5支付开发文档
  6. SAP Spartacus UnitDetailsComponent对应的UI插入,是在路由框架里完成的
  7. c语言大数倍数,leetcode-1346(检查整数及其两倍数是否存在)--C语言实现
  8. iDow Brand——关于一个商标的构思。
  9. 我的播客开通的第一天
  10. 一个wepy开发微信小程序时图片在真机上不显示的问题
  11. java中 15db9742_请问我这个报错[I@15db9742是怎么回事啊?
  12. Facebook广告设定技巧经验分享
  13. 可怕!离职都开始内卷了?!
  14. 拓端tecdat|matlab使用分位数随机森林(QRF)回归树检测异常值
  15. AIDE2.6.1安装及配置C/C++开发数据
  16. finereport与OA系统集成的完全方案
  17. 用python写恶搞病毒
  18. 岁月温柔-23 妈妈转到省医院第3天 突然icu有床位了
  19. 臀部肌群:肌肉图示和英文名称
  20. nape.dynamics.InteractionFilter

热门文章

  1. 蓝桥杯 ADV-228 算法提高 11-2删除重复元素
  2. 【软件测试】《软件测试技术基础》知识点整理
  3. LeetCode 279. Perfect Squares
  4. python修改pip源脚本_修改python的pip源为国内源
  5. 洛谷P1962 斐波那契数列
  6. 如何开发与设计一个爆款小游戏
  7. 在Apache上调试Asp.net 1.1/2.0代码
  8. Smack+OpenFire搭建IM通信,包含心跳和自动重连(Android实现)
  9. 如何构建自己的笔记系统?
  10. SCOM2012功能测试(25)—发布报表和收藏报表