Java内存模型

Java内存模型(JMM)主要目标是定义多线程的情况下线程访问变量的规则

JMM规定线程之间的共享变量存储在主内存中,每个线程都有一个本地内存(工作内存),本地内存存储了共享变量的副本。

关于线程安全

  • 什么是线程安全问题?

    多个线程同时共享同一个全局变量的操作时候,可能会受到其他线程的干扰,导致数据脏读。(数据一致性问题)

  • 如何解决线程安全问题?

    核心思想:在同一时刻,只能有一个线程执行。

    通过加锁使线程更加安全,也使程序的执行效率更低。

  • 衡量线程安全的3个要素:

    • 原子性:一个操作或者多个操作要么全部执行,要么都不执行
    • 可见性:多个线程访问同一变量,一个线程修改了变量的值,其他线程可以立即看到修改的值
    • 有序性:程序按照代码的顺序先后执行(与指令重排有关)

Volatile关键字

volatile是一种轻量级的同步机制,可以保证可见性【及时将修改的变量刷新到主内存中】,但不能保证原子性,并且禁止重排序。

volatile在多线程下的适用场景:一写多读

volatile如何保证内存可见性?

当一个线程对volatile修饰的变量进行写操作时,该线程中的本地内存的变量会被立刻刷新到主内存中。

当一个线程对volatile修饰的变量进行读操作时,该线程直接读取主内存的变量。

volatile能否保证线程安全?

不能,保证线程安全需要同时具备原子性,可见性和有序性。而volatile只能保证可见性和有序性,无法保证原子性。

Synchronized锁

核心思想:在多线程执行同一个方法时,只有获取到锁,才能进入方法里面执行

使用方式:

  • 修饰一个类:其作用的范围是synchronized后面括号括起来的部分,作用的对象是这个类的所有对象
  • 修饰一个方法:被修饰的方法称为同步方法,其作用的范围是整个方法,作用的对象是调用这个方法的对象
  • 修饰一个静态的方法:其作用的范围是整个方法,作用的对象是这个类的所有对象
  • 修饰一个代码块:被修饰的代码块称为同步语句块,其作用范围是大括号{}括起来的代码块,作用的对象是调用这个代码块的对象

重入锁

当一个线程已经获取到锁后,再次请求该锁,就可直接获取。(锁的传递性)

Synchronized属于可重入锁

Lock锁

自动挡Synchronized:Java关键字,在代码执行完或程序抛出异常自动释放锁

手动挡Lock:可以高度控制获取锁,释放锁的过程,扩展性极强

死锁

同步中嵌套同步,导致锁无法释放。

乐观锁与悲观锁

锁可以从不同的角度分类,乐观锁和悲观锁是其中一种。

乐观锁和悲观锁并不是锁的具体实现,而是并发控制的两种策略,或者说是抽象。

乐观锁(适合多读场景)

  • 思想:认为不会发生线程冲突

  • 执行流程,先读取数据,然后在更新前检查在读取至更新这段时间数据是否被修改

    • 未修改:直接更新数据
    • 已修改:重新读取,再次提交更新(或者放弃操作)

为什么乐观锁适合多读场景?

乐观锁是一种更新前的检查机制,相对于悲观锁来说在多读场景下可以减少锁的性能开销,对于多写场景,乐观锁会一直进入已修改,重新读取,再次提交的循环,反而带来更多的资源消耗。

悲观锁(适合多写场景)

  • 思想:认为一定会发生线程冲突

  • 执行流程:读取数据的时候上锁(其他用户无法读取),直到本次数据更新完成才会释放锁。在多写场景下,能保证较高的数据一致性。

【总的来说,乐观锁回滚重试,悲观锁阻塞事务】

线程安全&Java内存模型的更多相关文章

  1. Java 线程 — JMM Java内存模型

    JMM Java Memory Model,Java内存模型,属于语言级的内存模型 并发编程中存在的问题: 如何通信:用于线程之间交换信息.两种方式:共享内存,消息传递 如何同步:用于控制不同线程间操 ...

  2. 【Java线程】Java内存模型总结

    学习资料:http://www.infoq.com/cn/articles/Java-memory-model-1 Java的并发采用的是共享内存模型(而非消息传递模型),线程之间共享程序的公共状态, ...

  3. (转)【Java线程】Java内存模型总结

    Java的并发采用的是共享内存模型(而非消息传递模型),线程之间共享程序的公共状态,线程之间通过写-读内存中的公共状态来隐式进行通信.多个线程之间是不能直接传递数据交互的,它们之间的交互只能通过共享变 ...

  4. 深入理解Java虚拟机(第三版)-13.Java内存模型与线程

    13.Java内存模型与线程 1.Java内存模型 Java 内存模型的主要目的是定义程序中各种变量的访问规则,即关注在虚拟机中把变量值存储到主内存和从内存中取出变量值的底层细节 该变量指的是 实例字 ...

  5. java内存模型和线程

    概述 多任务的处理在现在的计算机中可以说是"标配"了,在许多的情况下,让计算机同时做几件事情,不仅是因为计算机的运算能力的强大,还有一个重要的原因是:cpu的运算速度和计算机的存储 ...

  6. java内存模型与线程(转) good

    java内存模型与线程 参考 http://baike.baidu.com/view/8657411.htm http://developer.51cto.com/art/201309/410971_ ...

  7. JAVA内存模型与线程

    概述 由于计算机的运算速度和它的存储和通讯子系统的速度差距巨大,大部分时间都花在IO,网络和数据库上.为了压榨CPU的运算能力,需要并发.另外,优秀的并发程序对于提高服务器的TPS有重要的意义. 硬件 ...

  8. Java内存模型与Java线程实现原理

    硬件的效率与一致性 基于高速缓存的存储交互很好的解决了处理器和内存的速度矛盾,但是也为计算机系统带来了更高的复杂度,因为引入了一个新问题:缓存一致性. 在多处理器系统中,每个处理器都有自己的高速缓存, ...

  9. 深入理解JVM(6)——Java内存模型和线程

    Java虚拟机规范中定义了Java内存模型(Java Memory Model,JMM)用来屏蔽掉各种硬件和操作系统的内存访问差异,以实现让Java程序在各种平台下都能达到一致的内存访问效果(“即Ja ...

随机推荐

  1. 自定义类支持foreach

    建议使用yield语句简化迭代 using System; using System.Collections; namespace 自定义类实现foreach { class A { int[] w; ...

  2. 老司机带你玩转面试(2):Redis 过期策略以及缓存雪崩、击穿、穿透

    前文回顾 建议前一篇文章没看过的同学先看下前面的文章: 「老司机带你玩转面试(1):缓存中间件 Redis 基础知识以及数据持久化」 过期策略 Redis 的过期策略都有哪些? 在聊这个问题之前,一定 ...

  3. 史上最全SpringBoot整合Mybatis案例

    摘要:如果小编说,SpringBoot是目前为止最好的框架,应该没有人会反驳吧?它的出现使得我们很容易就能搭建一个新应用.那么,SpringBoot与其他第三方框架的整合必定是我们需要关注的重点. 开 ...

  4. ajax原生js封装

    不带注释的 function ajax(json) { json.type = json.type ? json.type : 'get'; json.async = json.async == fa ...

  5. 软件测试面试题,十年HR面试经验分享

    WeChat[代码小姐],快和我们一起进大厂,挑战高薪吧. 问:你在测试中发现了一个  bug ,但是开发经理认为这不是一个  bug ,你应该怎样解决. 1.将问题提交到缺陷管理库里面进行备案.2. ...

  6. DJANGO-天天生鲜项目从0到1-012-订单-用户订单页面

    本项目基于B站UP主‘神奇的老黄’的教学视频‘天天生鲜Django项目’,视频讲的非常好,推荐新手观看学习 https://www.bilibili.com/video/BV1vt41147K8?p= ...

  7. Mysql concat() group_concat()用法

    数据库表: 关键字:concat 功能:将多个字符串连接成一个字符串 使用:concat(column1, column2,...)  字段中间可以加连字符 结果:连接参数产生的字符串,如果有任何一个 ...

  8. 初识Http

     HTTP是一个用在计算机世界里的协议,它确立了一种计算机之间交流通信的规范,以及相关的各种控制 和错误处理方式.  HTTP专门用来在两点之间传输数据,不能用于广播.寻址或路由. HTTP传输的是文 ...

  9. IO—》Properties类&序列化流与反序列化流

    Properties类 介绍:Properties 类表示了一个持久的属性集.Properties 可保存在流中或从流中加载.属性列表中每个键及其对应值都是一个字符串. Properties类特点: ...

  10. PHP array_reduce() 函数

    实例 发送数组中的值到用户自定义函数,并返回一个字符串: <?phpfunction myfunction($v1,$v2){return $v1 . "-" . $v2;} ...