12 2018 档案
摘要:虚拟机设计团队把类加载阶段中的“通过一个类的全限定名来获取描述此类的二进制字节流”这个动作放到Java虚拟机外部去实现,以便让应用程序自己决定如何去获取所需要的类。实现这个动作的代码模块称为“类加载器”。 类加载器在类层次划分、OSGi、热部署、代码加密等领域大放异彩,成为了Java技术体系中一块重
阅读全文
摘要:概述 虚拟机把描述类的数据从Class文件加载到内存,并对数据进行校验、转换解析和初始化,最终形成可以被虚拟机直接使用的Java类型,这就是虚拟机的类加载机制。 类加载的时机 类从被加载到虚拟机内存中开始,到卸载出内存为止,它的整个生命周期包括:加载(Loading)、验证(Verification
阅读全文
摘要:在开发过程中,合理地使用线程池能够带来3个好处。 第一:降低资源消耗。通过重复利用已创建的线程降低线程创建和销毁造成的销毁。 第二:提高响应速度。当任务到达时,任务可以不需要等到线程床架你就能立即执行。 第三:提高线程的可管理性,线程是稀缺资源,如果无限地创建,不仅会消耗系统资源,还会降级系统的五年
阅读全文
摘要:Mutex和ReentrantLock基本都是排他锁,这些锁在同一时刻只允许一个线程进行访问,而读写锁在同一时刻可以允许多个读线程访问,但是在写线程访问时,所有的读线程和其他写现场均被阻塞。读写锁维护了一对锁,一个读锁和一个写锁,通过分离读锁和写锁,使得并发性相比一般的排他锁有了很大提升。 除了保证
阅读全文
摘要:重入锁ReentrantLock,顾名思义,就是支持重进入的锁,它表示该锁能支持一个线程对资源的重复加锁。除此之外,该锁的还支持获取锁时的公平和非公平性选择。 ReentrantLock虽然没有像synchronized关键字一样支持隐式的重进入,但是在调用lock()方法时,已经获取到锁的线程,能
阅读全文
摘要:锁是用来控制多个线程访问共享资源的方式,一般来说,一个锁能够防止多个线程同时访问共享资源(但是有些锁可以允许多个线程并发的访问共享资源,比如读写锁)。 Lock接口(以及相关实现类)用来实现锁功能,它提供了与synchronized关键字类似的同步功能,只是在使用时需要显式地获取和释放锁。虽然它缺少
阅读全文
摘要: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),它是线程控制
阅读全文
摘要:集是一个集合,它可以快速地查找现有的元素。但是,要查看一个元素,需要有要查找元素的精确副本。这不是一种非常通用的查找方式。通常,我们知道某些键的信息,并想要查找与之对应的元素。映射(map)数据结构就是为此设计的。映射用来存放键/值对。如果提供了键,就能够查找到值。 基本映射操作 Java类库为映射
阅读全文
摘要:除了Map结尾的类之外,其他都实现了Collection接口,而以Map结尾的类实现了Map接口。 链表 在Java程序设计语言中,所有链表实际上都是双向链表的(double linked)——即每个节点还存放着指向前去节点的引用。 从链表中间删除一个元素是一个很轻松的操作, 即需要更新被删除元素附
阅读全文
摘要:super关键字 这里的关键字super具有不同的含义。语句 是“调用超类Employee中含有n、s、year、month和day参数的构造器”的简写形式。 由于Manager类的构造器不能访问Employee类的私有域,所以必须利用Employee类的构造器对这部分私有域进行初始化,我们可以通过
阅读全文
摘要:跟踪Spring MVC的请求 在请求离开浏览器时①,会带有用户所请求内容的信息,至少会包含请求的URL。 请求旅程的第一站是Spring的DispatcherServlet。与大多数基于Java的Web框架一样,SpringMVC所有的请求都会通过一个前端控制器(front controller)
阅读全文
摘要:Spring提供了几种技巧,可以帮助我们减少XML的配置数量。 自动装配(autowiring)有助于减少甚至消除配置元素和元素,让Spring自动识别如何装配Bean的依赖关系。 自动检测(autodiscovery)比自动装配更进了一步,让Spring能够自动识别哪些类需要被装配成Spring
阅读全文
摘要:声明Bean 创建Spring配置 从Spring3.0开始,Spring容器提供了两种配置Bean的方式。传统上,Spring使用一个或多个XML文件作为配置文件,而Spring3.0还同时提供了基于Java注解的配置方式,我们首先来关注传统的XML文件配置方式 在XML文件中声明Bean时, S
阅读全文
摘要:容纳Bean 在Spring中,应用对象生存于Spring容器中,如图所示,Spring容器可以创建、装载、配置这些Bean,并且可以管理它们的生命周期。 Spring的容器实现 Bean工厂( ):最简单的容器,提供基本的DI支持; 应用上下文( ):基于BeanFactory之上构建,提供面向应
阅读全文
摘要:Sping是一个开源框架,最早由Rod Johnson创建,并在《Expert One on ONe; JE22 Design and Development》这本著作中进行了介绍。Spring是为了解决企业级应用开发的复杂性而创建的,使用Spring可以让简单的JavaBean实现之前只有EJB才
阅读全文