摘要:
happens before是JMM最核心的概念。对应Java程序员来说,理解happens before是理解JMM的关键。 JMM的设计 首先,让我们来看JMM的设计意图。从JMM设计者的角度,在设计JMM时,需要考虑两个关键因素。 程序员对内存模型的使用。程序员系统内存模型易于理解、易于编程。 阅读全文
摘要:
与前面介绍的锁和volatile相比,对final域的读和写更像是普通恶的变量访问。 final域的重排序规则 对于final域,编译器和处理器要遵守两个重排序规则。 1)在构造函数内对一个final域的写入,与随后把这个被构造对象的引用赋值给一个引用变量,这两个操作之间不能重排序。 2)初次读一个 阅读全文
摘要:
锁的释放 获取建立的happens before关系 锁除了让临界区互斥执行外,还可以让释放锁的线程向获取一个锁的线程发送消息。 下面是锁释放 获取的示例代码。 假设线程A执行writer()方法,随后线程B执行reader()方法。根据happens before规则,这个过程包含的happens 阅读全文
摘要:
volatile的特性 理解volatile特性的一个好方法是把对volatile变量的单个读/写,堪称是使用同一个锁对这些单个读/写操作做了同步。 锁的happens before规则保证释放锁和获取锁的两个线程之间的内存可见性,这意味着对一个volatile变量的读,总是能看到(任意线程)对这个 阅读全文
摘要:
IDEA安装 按照最新版本有可能会有很多BUG的原则,我们就安装IDEA 2018.1.6版本的。 首先,我们到IDEA官网去下载IDEA, "官网链接" ,但是这个界面的版本一般为最新的。 这里我放出IDEA2018.1.6版本的下载连接,如果想下载其他版本可以试试改版本号。 "下载链接" 选择好 阅读全文
摘要:
认识前后端分离 在传统的web应用开发中,大多数的程序员会将浏览器作为前后端的分界线。将浏览器中为用户进行页面展示的部分称之为前端,而将运行在服务器,为前端提供业务逻辑和数据准备的所有代码统称为后端。 由于前后端分离这个概念相对来说刚出现不久,很多人都是只闻其声,不见其形,所以可能会对它产生一些误解 阅读全文
摘要:
ConcurreentHashMap的实现原理与使用 ConcurrentHashMap是线程安全且高效的HashMap。 为什么要使用ConcurrentHashMap 在并发编程中使用HashMap可能导致程序死循环。而使用线程安全的HashTable效率又非常低下,基于以上两个原因,便有了Co 阅读全文
摘要:
Java内存模型的基础 并发编程模型的两个关键问题 在并发编程种,需要处理两个关键问题:线程之间如何通信及线程之间如何同步(这里的线程是指并发执行的活动实体)。通信是指线程之间以何种机制来交换信息。在命令式编程种,线程之间的通信机制有两种:共享内存和消息传递。 在共享内存的并发模型里,线程之间共享程 阅读全文
摘要:
Java代码在编译后会变成Java字节码,字节码被类加载器加载到JVM里,JVM执行字节码,最终需要转化为汇编指令在CPU上执行,Java中所使用的并发机制依赖于JVM的实现和CPU的指令。 原子操作的实现原理 原子(atomic)本意是“不能被进一步分割的最小粒子”,而原子操作(atomic op 阅读全文
摘要:
Java代码在编译后会变成Java字节码,字节码被类加载器加载到JVM里,JVM执行字节码,最终需要转化为汇编指令在CPU上执行,Java中所使用的并发机制依赖于JVM的实现和CPU的指令。 volatile的应用 在多线程并发编程中synchronized和volatile都扮演着重要的角色,vo 阅读全文
摘要:
JDK版本 Vector简介 首先,Vector 是一个可增长的数组(和 ArrayList 类似),能够用索引直接找到元素,Vector 的容量可增可减 其次,Vector 使用变量 和 来进行容量的管理,关于容量和大小的说法,之前也提到过,容量是最多能够容纳多少元素,而大小是目前容纳了多少元素。 阅读全文
摘要:
JDK版本 HashSet简介 HashSet特点 非线程安全 允许null值 添加值得时候会先获取对象的hashCode方法,如果hashCode 方法返回的值一致,则再调用equals方法判断是否一致,如果不一致才add元素。 注意: 对于HashSet中保存的对象,请注意正确重写其equals 阅读全文
摘要:
JDK版本 HashMap简介 HashMap基于哈希表的 Map 接口的实现。此实现提供所有可选的映射操作,并允许使用 null 值和 null 键。(除了不同步和允许使用 null 之外,HashMap 类与 Hashtable 大致相同。)此类不保证映射的顺序,特别是它不保证该顺序恒久不变。 阅读全文
摘要:
JDK版本 LinkedList简介 LinkedList 是一个继承于AbstractSequentialList的双向链表。它也可以被当作堆栈、队列或双端队列进行操作。 LinkedList 实现 List 接口,能对它进行队列操作。 LinkedList 实现 Deque 接口,即能将Link 阅读全文
摘要:
如果说收集算法是内存回收的方法论,垃圾收集器就是内存回收的具体实现。Java虚拟机规范中对垃圾收集器应该如何实现并没有任何规定,因此不同的厂商、不同版本的虚拟机所提供的垃圾收集器都可能会有很大的差别,并且一般都会提供参数供用户根据自己的应用特点和要求组合出各个年代所使用的收集器。这里讨论的收集器基于 阅读全文
摘要:
Java技术体系中所提倡的自动内存管理最终可以归结为自动化地解决了两个问题:给对象分配内存以及回收分配给对象的内存。 对象的内存分配,往大方向上讲,就是在堆上分配(但也可能经过JIT编译后被拆散为标量类型并间接地在栈上分配),对象主要分配在新生代地Eden区上,如果启动了本地线程分配缓冲,将按线程优 阅读全文
摘要:
概述 说起垃圾收集(Garbage Collection,GC),大部分人都把这项技术当做Java语言的伴生产物。事实上,GC的历史远远比Java久远,1960年诞生于MIT的Lisp是第一门真正使用内存动态分配和垃圾收集技术的语言。当Lisp还在胚胎时期时,人们就在思考GC需要完成的三件事: 那些 阅读全文
摘要:
由于垃圾收集算法的实现涉及大量的程序细节,而且各个平台的虚拟机操作内存的方法又各不相同,因此不打算过多地讨论算法地实现,只是介绍几种算法地思想及其发展过程。 标记 清除算法 最基础地收集算法是“标记 清除”(Mark Sweep)算法,算法分为”标记“和”清除“两个阶段:首先标记出所有需要回收的对象 阅读全文
摘要:
Java内存区域与内存溢出异常 Java和C++之间有一堵由内存动态分配和垃圾手机技术所围成的高墙,墙外面的人想进去,墙里面的人却想出来。 概述 对于从事C和C++程序开发的开发人员来说,在内存管理领域,他们即是拥有最高权力的皇帝,又是从事最基础工作的劳动人民——既有用每一个对象的“所有权”,又担负 阅读全文
摘要:
多任务(multitasking):在同一时刻运行多个程序的能力。 并发执行的进程数目并不是由CPU数目制约的。操作系统将CPU的时间片分配给每一个进程,给人并发处理的感觉。 多线程程序在较低的层次上扩展了多任务的概念:一个程序同时执行多个任务。通常,每一个任务称为线程(thread),它是线程控制 阅读全文