写在前面 上一篇文章原子性问题的宏观理解 带领大家了解了锁和资源的模型,有了这篇文章的铺垫,相信理解这一篇文章就非常轻松了 当我们要保护单个资源并对其进行修改其实很简单,只需按照下图分三步走 1. 创建受保护资源 R 的锁 2. 加锁进入临界区 3. 解锁走出临界区 上图的关键是「R1 的锁保护 R1」的指向关系是否正确 如果都是保护单个资源这样简单,程序猿的世界该有多美好,可惜并不是,通常我们需要保护多个资源 保护多个资源 保护多个没有关系的资源 如果多个资源没有关系,那就是保护一个资源模型的复制,同样非常简单,且看下图: 比如现实中银行取款和修改密码操作。 银行取
写在前面 Java 后端程序员应该会遇到读取 Excel 信息到 DB 等相关需求,脑海中可能突然间想起 Apache POI 这个技术解决方案,但是当 Excel 的数据量非常大的时候,你也许发现,POI 是将整个 Excel 的内容全部读出来放入到内存中,所以内存消耗非常严重,如果同时进行包含大数据量的 Excel 读操作,很容易造成内存溢出问题 但 EasyExcel 的出现很好的解决了 POI 相关问题,原本一个 3M 的 Excel 用 POI 需要100M左右内存, 而 EasyExcel 可以将其降低到几 M,同时再大的 Excel 都不会出现内存溢出的情况,因为是逐行读取 E
写在前面 在 可见性有序性,Happens-before来搞定 文章中,happens-before 的原则之一: volatile变量规则 对一个 volatile 域的写, happens-before 于任意后续对这个 volatile 域的读 按理说了解了这个规则,对 volatile 的使用就已经足够了,但是面试官可是喜欢刨根问到底的,为了更透彻的了解 volatile 的内存语义与读写语义,为了面试多一些谈资进而获得一些加分项,同时尽早填补前序文章留下的坑,于是乎这篇文章就这样尴尬的诞生了 happens-before 之 volatile 变量规则 下面的表格你还记得吗?
上一篇文章 可见性有序性,Happens-before来搞定,解决了并发三大问题中的两个,今天我们就聊聊如何解决原子性问题 原子性问题的源头就是 线程切换,但在多核 CPU 的大背景下,不允许线程切换是不可能的,正所谓「魔高一尺,道高一丈」,新规矩来了: 互斥: 同一时刻只有一个线程执行 实际上,上面这句话的意思是: 对共享变量的修改是互斥的,也就是说线程 A 修改共享变量时其他线程不能修改,这就不存在操作被打断的问题了,那么如何实现互斥呢? 锁 对并发有所了解的小伙伴马上就能想到 锁 这个概念,并且你的第一反应很可能就是使用 synchronized,这里列出来你常见的 syn
写在前面 上一篇文章并发 Bug 之源有三,请睁大眼睛看清它们 谈到了可见性/原子性/有序性三个问题,这些问题通常违背我们的直觉和思考模式,也就导致了很多并发 Bug * 为了解决 CPU,内存,IO 的短板,增加了缓存,但这导致了可见性问题 * 编译器/处理器擅自优化 ( Java代码在编译后会变成 Java 字节码, 字节码被类加载器加载到 JVM 里, JVM 执行字节码, 最终需要转化为汇编指令在 CPU 上执行) ,导致有序性问题 初衷是好的,但引发了新问题,最有效的办法就禁止缓存和编译优化,问题虽然能解决,但「又回到最初的起点,呆呆地站在镜子前」是很尴尬的,我们程序的性能就
写在前面 * 生活中你一定听说过——能者多劳 * 作为 Java 程序员,你一定听过——这个功能请求慢,能加一层缓存或优化一下 SQL 吗? * 看过中国古代神话故事的也一定听过——天上一天,地上一年 一切设计来源于生活,上一章 学并发编程,透彻理解这三个核心是关键 中有讲过,作为”资本家”,你要尽可能的榨取 CPU,内存与 IO 的剩余价值,但三者完成任务的速度相差很大,CPU > 内存 > IO分,CPU 是天,那内存就是地,内存是天,那 IO 就是地,那怎样平衡三者,提升整体速度呢? 1. CPU 增加缓存,还不止一层缓存,平衡内存的慢 2. CPU 能者多劳,通过分时
拦截器介绍 Mybatis Interceptor 在 Mybatis 中被当作 Plugin(插件),不知道为什么,但确实是在 org.apache.ibatis.plugin 包下面 既然是拦截器,可以拦截哪些内容呢?试想一下…… 当程序写到持久层时,Mybatis 会 执行 指定 SQL 语句,并处理 请求参数 和 返回值。没错,Mybatis 拦截器可以帮助我们处理上述内容,请看官网的 Plugins 的片段, 内容不多 1 2 3 4 5 6 7 8 // 执行 Executor (update, query, flushStatements, commit, rollb
关于 Java String,这是面试的基础,但是还有很多童鞋不能说清楚,所以本文将简单而又透彻的说明一下那个让你迷惑的 String 在 Java 中,我们有两种方式创建一个字符串 1 2 String x = "abc"; String y = new String("abc"); 你常见也常写第一种,很少见第二种,但面试还总问这类问题,双引号和构造器两种形式创建字符串到底有什么差别呢? 先来看例子 例子 1 1 2 3 4 String a = "abcd"; String b = "abcd"; System.out.println(a == b); // T
写在前面 上一篇文章这次走进并发的世界,请不要错过 给大家带了并发编程的开胃菜,接下来我们逐步上正餐,在吃正餐之前,我还要引用那首诗词: 「横看成岭侧成峰,远近高低各不同」,远看看轮廓,近看看细节,不断切换思维或视角来学习 远看并发,并发编程可以抽象成三个核心问题: 分工、同步/协作、互斥 如果你已经工作了,那么你一定听说过或者正在应用敏捷开发模式来交付日常的工作任务,我们就用你熟悉的流程来解释这三个核心问题 分工 将当前 Sprint 的 Story 拆分成「合适」大小的 Task,并且安排给「合适」的 Team Member 去完成 这里面用了两个「合适」,将 Story 拆分
写在前面 Java 有进阶,其名为并发,并发知识之大,一口吃不下。那好,请您多吃几口,又没说一顿吃完,细嚼慢咽才有味. 所有 Java 书籍都将并发编程放在其高级/进阶篇章中,其重要性不言而喻,学好并发也是自身走入高级行列的必备素质之一 并发/并行,进程/线程 这些概念总是显得过于抽象,因为这是与操作系统沟通用到的词汇,就像我们习惯了使用十进制算法,二进制和 16 进制就需要思维的切换;生活中,我们彼此总是不能互相理解,平静之后,我们知道要换位思考;程序的世界也一样,为了更好的理解问题,你也要站在操作系统的角度来思考问题,但当你尝试理解对方时,是违背自己认知习惯的,所以有些困难在所难免 生



Copyright 2018-2019 Tanθ's Blog   |   辽ICP备19017651号-1   |     站点总字数: 277.7k 字   |   载入天数...载入时分秒...   |  站点地图   |  站长统计
  总访问量:  次  总访问人数:  人

博客内容遵循 署名-非商业性使用-相同方式共享 4.0 国际 (CC BY-NC-SA 4.0) 协议