首页 文章 精选 留言 我的

精选列表

搜索[Java],共10000篇文章
优秀的个人博客,低调大师

Java多线程 synchronized与可见性的关系以及可见性问题总结

@[toc] 能保证可见性的措施 除了volatile 可以让变量保证可见性外. 如下这篇文章中,介绍的happens-before九大规则. 都是能够保证可见性的. 其中就包含了锁操作(synchronized 和 lock) 和 volatile 修饰的变量 https://javaweixin6.blog.csdn.net/article/details/108423590 synchronized作用的升华 synchronized 关键字不仅仅保证了其代码块中的原子性 ,也保证了可见性. 例如如下代码中的i++操作 , 使用了synchronized 代码块保护起来, 使得两个线程对其相加的时候, 可以正确的得出20万的结果. 这个结果不仅仅是保证了其i相加时候的原子性. 也说明保证了其可见性. 否则一个线程加完了之后, 另外一个线程没有获取i的最新的值的话, 也会导致相加的结果变少. synchronized 不仅仅让被保护的代码安全, 还会保证对synchronized 修饰的代码执行完毕之后, 下一个synchronized 进入之前, 整个synchronized 保护的代码块,都会被之后执行的代码看得到. 并且synchronized 之前的所有的代码也会被看到 . 如下面这幅图, 线程B拿到锁之后, 对于线程A的所有的操作都是可见的. 这是一个连带效应. 如下的代码中, 对可见性的代码进行了修改. 把赋值操作的方法中, 最后一个变量的赋值, 加上了synchronized修饰. 打印的方法中, 第一行代码加上了synchronized修饰. 这样就保证了原子性和可见性. 写线程在执行完成d=6的时候, 会释放锁. 打印的线程获得锁的时候, 就能知道写线程的所有的操作, 获得其最新的值. 完整的代码如下. package com.thread.jmm; /** * 类名称:FieldVisibility * 类描述: 演示可见性问题 * * @author: https://javaweixin6.blog.csdn.net/ * 创建时间:2020/9/5 14:31 * Version 1.0 */ public class FieldVisibility { int a = 1; int b = 2; int c = 3; int d = 4; //给a 赋值, 并把值给b private void change() { a = 3; b = a; c = a; synchronized (this) { d = 6; } } /** * 打印出a b */ private void print() { synchronized (this) { int aa = a ; } int bb = b ; int cc = c ; int dd = d ; System.out.println("b=" + b + ";a=" + a); } public static void main(String[] args) { while (true) { FieldVisibility test = new FieldVisibility(); new Thread(() -> { try { Thread.sleep(1); } catch (InterruptedException e) { e.printStackTrace(); } //给 a b 重新赋值 test.change(); }).start(); new Thread(() -> { try { Thread.sleep(1); } catch (InterruptedException e) { e.printStackTrace(); } //给 a b 打印出来 test.print(); }).start(); } } } 可见性总结 演示什么是可见性 https://javaweixin6.blog.csdn.net/article/details/108419450 为什么会有可见性问题: CPU的多级缓存, 导致没有从主内存中获取最新值 . https://javaweixin6.blog.csdn.net/article/details/108421939 JMM的抽象 : 主内存和本地内存. https://javaweixin6.blog.csdn.net/article/details/108422267 happens-before原则与规则https://javaweixin6.blog.csdn.net/article/details/108422677 https://javaweixin6.blog.csdn.net/article/details/108423590 volatile 关键字 https://javaweixin6.blog.csdn.net/article/details/108431303 能保证可见性的措施, 与happens-before原则一致. 对synchronized认识的升华, 不仅仅是保证了原子性, 也保证了可见性. 同时 对于synchronized修饰的代码, synchronized之前执行的代码也是可见的 .

资源下载

更多资源
Mario

Mario

马里奥是站在游戏界顶峰的超人气多面角色。马里奥靠吃蘑菇成长,特征是大鼻子、头戴帽子、身穿背带裤,还留着胡子。与他的双胞胎兄弟路易基一起,长年担任任天堂的招牌角色。

Spring

Spring

Spring框架(Spring Framework)是由Rod Johnson于2002年提出的开源Java企业级应用框架,旨在通过使用JavaBean替代传统EJB实现方式降低企业级编程开发的复杂性。该框架基于简单性、可测试性和松耦合性设计理念,提供核心容器、应用上下文、数据访问集成等模块,支持整合Hibernate、Struts等第三方框架,其适用范围不仅限于服务器端开发,绝大多数Java应用均可从中受益。

Rocky Linux

Rocky Linux

Rocky Linux(中文名:洛基)是由Gregory Kurtzer于2020年12月发起的企业级Linux发行版,作为CentOS稳定版停止维护后与RHEL(Red Hat Enterprise Linux)完全兼容的开源替代方案,由社区拥有并管理,支持x86_64、aarch64等架构。其通过重新编译RHEL源代码提供长期稳定性,采用模块化包装和SELinux安全架构,默认包含GNOME桌面环境及XFS文件系统,支持十年生命周期更新。

WebStorm

WebStorm

WebStorm 是jetbrains公司旗下一款JavaScript 开发工具。目前已经被广大中国JS开发者誉为“Web前端开发神器”、“最强大的HTML5编辑器”、“最智能的JavaScript IDE”等。与IntelliJ IDEA同源,继承了IntelliJ IDEA强大的JS部分的功能。

用户登录
用户注册