java并发学习--第十章 java内存模型的内存语义

一、锁的内存语义

  所为的java内存模型的内存语义指的就是在JVM中的实现原则。

  锁的内存语义:锁除了让临界区互斥执行外,还可以让释放锁的线程向获取同一个锁的线程发送消息。

  我们把上面这句话再整理下:

  当线程释放锁时,JMM会把该线程对应的本地内存中的共享变量刷新到主内存中。

 当线程获取锁时,JMM会把该线程对应的本地内存置为无效。从而使得被监视器保护的临界区代码必须要从主内存中去读取共享变量。 

  锁的内存语义实现:

  synchronized、ReentrantLock;

二、volatile内存语义

  volatile的内存语义与锁的内存语义相识:

  1.当写一个volatile变量时,java内存模型会吧线程对应的本地内存中的共享变量刷新到主内存中。

  2.当读一个volatile变量时,java内存模型会把当前线程对应内存中的共享变量置为无效 ,然后在主内存中读取共享变量。

  我们可以看到volatile写的内存语义和释放锁的内存语义类似,volatile读的内存语义和获取锁的内存语义类似。

三、final的内存语义

  final域的内存语义主要是研究其指令重排序规则,主要分为写、读两种指令重排序规则

  1.写final域的指令重排序规则

  ①写final域的重排序规则禁止把final域的写重排序到构造方法外

  ②静态代码块中不能对常量赋值,因为静态代码块是在类加载时生成的,常量是类初始化创建的。我们知道,类的加载中,加载先与初始化进行,所有不能。

  ③编译器会在final域的写之后,在构造方法执行完毕之前,插入一个内存屏障 store store,保证出来器把final域的写操作在构造方法中执行。

  2.读final域的重排序规则

  在一个线程中,初次读对象引用和初次读该对象所包含的final域,java内存模型禁止处理器重排这两个操作。

  
  

  

  

原文地址:https://www.cnblogs.com/daijiting/p/11787649.html

时间: 2024-11-05 14:56:14

java并发学习--第十章 java内存模型的内存语义的相关文章

Java 并发学习之 JMM

Java 并发学习之 JMM 顺序一致性模型与 JMM 顺序一致性模型是一种理想的内存模型,在这个模型下,指令是严格按照代码的编写顺序执行,同时所有线程只能看到同一个内存区且对内存区的操作都是互斥的,内存对所有线程都是可见的. JMM 中,由于每个线程有自己的工作内存,很多情况下,只是对工作内存中的变量副本进行修改而未真正同步到主内存中,因此每个线程对内存的更改对其他线程都是不可见的,同时出于对性能的优化,指令的顺序经过编译器和处理器的重排,其执行的顺序跟代码的编写顺序很有可能不一样.所以导致了

Java并发学习笔记(九)-原子类AtomicInteger

AtomicInteger能够保证对一个整型的操作是原子性.像i++这个操作不是原子操作,存在竞态条件,所以需要加锁,但是加锁的性能不高,如果仅仅为了对一个整数加1.我们来看下他的实现. private volatile int value; AtomicInteger本身持有一个整型变量,所有的操作都是基于这个变量的.变量由violate修饰,这个变量是保证可见性的,具体可见另一篇博客 Java并发学习笔记(六)-互斥性和内存可见性. 来看一下对value加1的操作 public final

Java并发指南开篇:Java并发编程学习大纲

Java并发编程一直是Java程序员必须懂但又是很难懂的技术内容. 这里不仅仅是指使用简单的多线程编程,或者使用juc的某个类.当然这些都是并发编程的基本知识,除了使用这些工具以外,Java并发编程中涉及到的技术原理十分丰富.为了更好地把并发知识形成一个体系,也鉴于本人没有能力写出这类文章,于是参考几位并发编程专家的博客和书籍,做一个简单的整理. 一:并发基础和多线程 首先需要学习的就是并发的基础知识,什么是并发,为什么要并发,多线程的概念,线程安全的概念等. 然后学会使用Java中的Threa

Java并发学习之五——线程的睡眠和恢复

本文是学习网络上的文章时的总结,感谢大家无私的分享. 1.Thread类的sleep方法,可以使线程睡眠.此方法接收一个整数作为参数,表示线程暂停运行的毫秒数.在调用sleep方法后,当时间结束时,JVM会安排他们CPU时间,线程会继续按指令执行. 另一种可能是使用一个有TimeUnit列举元素的sleep方法,使用线程类的sleep方法让当前线程睡眠,但是它接收的参数单位后会转成毫秒的. 2.当你调用sleep()方法,Thread离开CPU并在一段时间内停止运行.在这段时间内,他是不消耗CP

Java并发学习之二——获取和设置线程信息

本文是学习网络上的文章时的总结,感谢大家无私的分享. Thread类的对象中保存了一些属性信息能够帮助我们辨别每一个线程,知道它的一些信息 ID:每个线程的独特标示: Name:线程的名称: Priority:线程对象的优先级.优先级别在1-10之间,1是最低级,10是最高级. Status:线程状态.在java中,线程只有6种状态:new,runnable,blocked,waiting,time waiting 或terminated. 现在写一个程序,将线程的信息保存到文件中方便查看 pa

Java并发学习之七——守护线程

本文是学习网络上的文章时的总结,感谢大家无私的分享. 1.Java有两种Thread:"守护线程Daemon"与"用户线程User".用户线程:Java虚拟机在它所有非守护线程已经离开后自动离开:守护线程:则是用来服务用户线程的,如果没有其他用户线程在运行,那么就没有可服务对象,也就没有理由继续下去. 2.setDaemon(boolean on)方法可以方便的设置线程的Daemon模式,true为Daemon模式,此方法必须在线程启动之前调用,当线程正在运行时调用

Java并发学习之四——操作线程的中断机制

本文是学习网络上的文章时的总结,感谢大家无私的分享. 1.如果线程实现的是由复杂算法分成的一些方法,或者他的方法有递归调用,那么我们可以用更好的机制来控制线程中断.为了这个Java提供了InterruptedException异常.当你检测到程序的中断并在run()方法内捕获,你可以抛这个异常. 2.InterruptedException异常是由一些与并发API相关的Java方法,如sleep()抛出的. 下面以程序解释 package chapter; import java.io.File

【Todo】Java并发学习 & 示例练习及代码

接上一篇:http://www.cnblogs.com/charlesblc/p/6097111.html <Java并发学习 & Executor学习 & 异常逃逸 & 同步互斥Best Practice & wait/notify, conditon#await/signal> 原文参考:http://www.ciaoshen.com/2016/10/28/tij4-21/ <Thinking in Java 读书笔记:第二十一章 - 并发> 第

Java并发学习之八——在线程中处理不受控制的异常

本文是学习网络上的文章时的总结,感谢大家无私的分享. 1.Java里有2种异常: 检查异常:这些异常必须强制捕获她们或在一个方法里的throws子句中. 未检查异常:这些异常不用强制捕获它们. 2.在一个线程对象的run()方法里抛出一个检查异常,我们必须捕获并处理她们.因为run()方法不接受throws子句.当一个非检查异常抛出,默认的的行为是在控制台写下stack trace并退出程序. package chapter; public class Main8 { /** * <p> *