JAVA内存模型

  在多线程这一系列中,不去探究内存模型的底层

一、什么是内存模型,为什么需要它

  在现代多核处理器中,每个处理器都有自己的缓存,定期的与主内存进行协调;

  想要确保每个处理器在任意时刻知道其他处理器正在进行的工作,将需要很大的开销;且通常是没必要的

  我们只有在需要跨线程共享数据时,才需要知道信息;而在JAVA中就是通过正确的同步来实现

  1.重排序

    如下:判断输出的值将十分困难

public class PossibleReordering {
static int x = 0, y = 0;
static int a = 0, b = 0; /**
* 判断输出值将会非常困难:
* 1:多线程之间的切换,导致可能的输出值:(0,1)(1,0)(1,1)
* 2.指令重排序:one线程如a=1和x=b之间重排序,x=b(0),然后other线程被调度执行y=a(0),将导致(0,0)
*/
public static void main(String[] args) throws InterruptedException {
Thread one = new Thread(new Runnable() {
public void run() {
a = 1;
x = b;
}
});
Thread other = new Thread(new Runnable() {
public void run() {
b = 1;
y = a;
}
});
one.start();
other.start();
one.join();
other.join();
System.out.println("( " + x + "," + y + ")");
}
}

  2.JAVA内存模型简介

    偏序关系:反对称、自反和传递属性;但是对于任意的两个元素A和B,并不一定满足A偏向B或B偏向A的关系

      如:A和B之间我更偏向B,但是我没必要明确的做出选择

    JMM为程序中所有的操作定义了一个偏序关系,称之为Happens-Before;要想保证执行B操作的线程看到执行A操作的线程的结果,无论AB是否在同一线程,必须满足Happens-Before关系,否则JVM就会对其重排序

    

如:加锁操作,就可以预知执行顺序,多个线程之间就符合Happens-Before,不加锁则无法判断线程之间的调度,

  3.发布

    真正原因:发布一个共享对象  和  在另一个线程中访问该对象之间没有Happens-Before关系;由于指令重排序,导致对象没有正确构建则被发布

public class UnsafeLazyInitialization {
private static Resource resource; /**
* 除了竟态条件问题检查后执行,还有不安全发布的问题
* 如:一个线程A进来,看到resource为null,则实例化并返回;另一个线程B进来看到resource不为null直接返回
* 如果在线程A中对resource进行了修改,则可能在线程B中看不到resource的正确状态
*/
public static Resource getInstance() {
if (resource == null)
resource = new Resource(); // unsafe publication
return resource;
} static class Resource {
}
}

    

java并发编程(9)内存模型的更多相关文章

  1. Java并发编程、内存模型与Volatile

    http://www.importnew.com/24082.html  volatile关键字 http://www.importnew.com/16142.html  ConcurrentHash ...

  2. x86-TSO : 适用于x86体系架构并发编程的内存模型

    Abstract : 如今大数据,云计算,分布式系统等对算力要求高的方向如火如荼.提升计算机算力的一个低成本方法是增加CPU核心,而不是提高单个硬件工作效率. 这就要求软件开发者们能准确,熟悉地运用高 ...

  3. 【并发编程】- 内存模型(针对JSR-133内存模型)篇

    并发编程模型 1.两个关键问题 1)线程之间如何通信 共享内存 程之间共享程序的公共状态,通过写-读内存中的公共状态进行隐式通信 消息传递 程之间没有公共状态,线程之间必须通过发送消息来显式进行通信 ...

  4. 《Java并发编程的艺术》笔记

    第1章 并发编程的挑战 1.1 上下文切换 CPU通过时间片分配算法来循环执行任务,任务从保存到再加载的过程就是一次上下文切换. 减少上下文切换的方法有4种:无锁并发编程.CAS算法.使用最少线程.使 ...

  5. Java并发编程:JMM(Java内存模型)和volatile

    1. 并发编程的3个概念 并发编程时,要想并发程序正确地执行,必须要保证原子性.可见性和有序性.只要有一个没有被保证,就有可能会导致程序运行不正确. 1.1. 原子性 原子性:即一个或多个操作要么全部 ...

  6. Java并发编程:JMM (Java内存模型) 以及与volatile关键字详解

    目录 计算机系统的一致性 Java内存模型 内存模型的3个重要特征 原子性 可见性 有序性 指令重排序 volatile关键字 保证可见性和防止指令重排 不能保证原子性 计算机系统的一致性 在现代计算 ...

  7. Java并发编程(1)-Java内存模型

    本文主要是学习Java内存模型的笔记以及加上自己的一些案例分享,如有错误之处请指出. 一 Java内存模型的基础 1.并发编程模型的两个问题 在并发编程中,需要了解并会处理这两个关键问题: 1.1.线 ...

  8. Java并发编程里的volatile。Java内存模型核CPU内存架构的对应关系

    CPU内存架构:https://www.jianshu.com/p/3d1eb589b48e Java内存模型:https://www.jianshu.com/p/27a9003c33f4 多线程下的 ...

  9. Java并发编程实战 第16章 Java内存模型

    什么是内存模型 JMM(Java内存模型)规定了JVM必须遵循一组最小保证,这组保证规定了对变量的写入操作在何时将对其他线程可见. JMM为程序中所有的操作定义了一个偏序关系,称为Happens-Be ...

  10. Java并发编程-Java内存模型

    JVM内存结构与Java内存模型经常会混淆在一起,本文将对Java内存模型进行详细说明,并解释Java内存模型在线程通信方面起到的作用. 我们常说的JVM内存模式指的是JVM的内存分区:而Java内存 ...

随机推荐

  1. c# 前后日期设置

    List<string> list = new List<string>(); //根据当月 显示前6个月 for(int i=0;i<6;i++) { list.add ...

  2. (转载)Oracle的悲观锁和乐观锁

    为了得到最大的性能,一般数据库都有并发机制,不过带来的问题就是数据访问的冲突.为了解决这个问题,大多数数据库用的方法就是数据的锁定. 数据的锁定分为两种方法,第一种叫做悲观锁,第二种叫做乐观锁.什么叫 ...

  3. Oracle数据库exp和imp方式导数据

    这里导入导出路径都在D盘下,默认文件名为:example.dmpexp方式导出数据相关参数项如下: 关键字  说明  默认USERID                     用户名/口令FULL   ...

  4. Ubuntu16.04 - 怎么能够更好设置PATH变量,便于管理?

    “/etc/profile”是linux里面的全局变量设置文件,加入这里的PATH变量,全局都可以使用,非常方便.加入时候很简单了,直接在PATH末尾加入":+要加入的变量"就可以 ...

  5. 【OCP认证12c题库】CUUG 071题库考试原题及答案(25)

    25. choose the best answer Evaluate the following SQL statement: ALTER TABLE hr.emp SET UNUSED (mgr_ ...

  6. “全栈2019”Java异常第十六章:Throwable详解

    难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"Java异 ...

  7. django rest framework 向数据库中插入数据时处理外键的方法

    一.models.py中 from django.db import models class UserModel(models.Model) user_name = models.CharField ...

  8. jmeter+ant+jenkins+mac报告优化(二):添加90% Line和QPS

    一.优化内容 1.Summary中只标红Failures数 2.Pages页面按Average Time倒序排序 3.Average Time超过2s标黄显示 4.Pagelist 模块中针对错误和超 ...

  9. php防止网站被刷新

    在实际应用中,总会遇到某些页面被恶意用户刷新.当你的系统在某些模块没有使用缓存的时候,频繁的刷新会导致数据库吃紧.下面附上一段代码,防止频繁的刷新造成的死机情况. 主要是从 session方面进行限制 ...

  10. 空行会影响 Java 编译吗?

    简评:往往越简单的问题越容易被人们忽略. 问题 这个月的 Stack Overflow 有篇热门文章是国外有位开发者提出: 当我仅仅对 Java 类增加了一行空行,为什么编译后得到了两个不同的字节码文 ...