Java
文章平均质量分 88
dm_vincent
这个作者很懒,什么都没留下…
展开
-
[Java 并发基础] 也来聊聊Java多线程中的一些概念问题
文章导航什么是多线程并发为什么要进行多线程并发编程线程安全Java内存模型映射到现代硬件架构内存可见性问题的解决方案synchronizedvolatile原子性和线程安全,锁和内存可见性什么是多线程并发理清并发和并行的概念。并发:同一个时间段内多个任务同时都在执行,并且都没有执行结束。并行:在单位时间内多个任务同时在执行。并发任务强调在一个时间段内同时执行,而一个时间段是由多个单位时间...原创 2019-07-13 20:43:12 · 878 阅读 · 0 评论 -
[AOP] 1. AOP的由来以及快速上手
AOP从何而来技术的演化从来都不是随机现象。往往都是为了应对某种特定的问题,而形成的一系列切实可行解决方案或者优雅的最佳实践,然后把它们汇聚在一起,就形成了一个工具,一个库或者是一个框架。为应对Cross-cutting问题而生要了解AOP(Aspect Oriented Programming,面向切面编程)从何而来,首先来看看下面这段代码:public void doBusinessLogic(原创 2017-02-25 14:44:22 · 3242 阅读 · 0 评论 -
[JavaEE - JPA] 性能优化: 4种触发懒加载的方式
在一个JPA应用中,可以通过懒加载来提高应用的性能。这一点毋庸置疑,但是懒加载不等于不加载,在某个时刻还是需要加载这些数据的,那么如何触发这个加载的行为才能够事半功倍呢?这里我想说一点题外话,面试的时候我也会考察被面试者对于JPA/Hibernate的看法,得到的答复通常都包含了对JPA/Hibernate的一些”鄙夷”,比如JPA/Hibernate性能太菜了,现在主流的持久层框架是MyBatis原创 2016-11-27 23:16:11 · 18141 阅读 · 0 评论 -
[JavaEE - JPA] 性能优化: 如何定位性能问题
要想解决性能问题,首先得要有办法定位问题。而JPA的性能问题,可以说99%都是因为JPA Provider(一般使用的都是Hibernate,或者EclipseLink)生成的SQL效率低下或者生成并执行了你意料之外的SQL。针对这个问题,其实不需要多么复杂的调试工具,一般而言JPA Provider就会提供一些基础的性能分析工具,以Hibernate为例(EclipseLink等其它JPA Pro原创 2016-12-03 19:26:07 · 11105 阅读 · 5 评论 -
[JavaEE - JPA] 7. ORM的核心注解 - 关系类型
本文继续介绍JPA ORM的核心注解中和关系映射相关的部分。关系映射的处理绝对是一个JPA应用最为重要的部分之一。关系映射处理的好,不仅仅是建模上的成功,而且在程序性能上也会更胜一筹。关系映射处理的不好很容易造成程序性能底下,各种Bug频繁出现,而且这些Bug通常还会比较隐蔽,总是在关键时刻掉链子。我想这也是为什么很多开发人员说JPA入门容易,精通难得原因之一。因为关系确实不是那么好处理的,不仅需要原创 2016-10-20 21:40:11 · 3305 阅读 · 1 评论 -
[JavaEE - JPA] 6. ORM的核心注解 - 基础类型以及嵌套类型
本文继续介绍JPA ORM的核心注解中和基础类型映射相关的部分。基础类型映射所谓的基础类型映射,实际上就是Java中定义的数据类型应该如何被JDBC转换成数据库所支持的数据类型。而这些基础类型,主要包括了以下9种:简单类型:byte,int,short,long,boolean,char,float以及double简单类型对应的包装类型:Byte,Integer,Short,Long,Boole原创 2016-10-17 22:26:29 · 3333 阅读 · 0 评论 -
[JavaEE - JPA] 5. ORM的核心注解 - 访问方式,表映射以及主键生成
从本篇文章开始,会系统性地介绍JPA中用来实现对象关系映射(Object Relational Mapping)的核心注解,以及基础类型,关系类型,嵌套类型以及集合类型的映射方式。注解种类在探讨实现JPA中各种映射的方式之前,可以先看看JPA中的注解类型。 由于ORM这一机制涉及到了两个方面:对象(内存模型)以关系数据(关系型数据库)。而显然我们在配置ORM的各种规则时,只能在Java程序中完成。原创 2016-09-28 23:40:38 · 3750 阅读 · 0 评论 -
[JavaEE - JPA] 4. EntityManager相关核心概念
前三篇文章花了一些笔墨介绍了事务的概念以及在EJB和Spring Framework中分别是如何完成事务管理的。之所谓花了比较大的代价来介绍事务主要也是因为不管在什么类型的持久化应用中,都包含下面两个关键点:事务管理对象关系映射(ORM)而JPA主要定义的就是和对象关系映射(ORM)相关的内容。从本篇文章开始,会系统性地介绍JPA的方方面面。核心概念及其关联关系首先,当然原创 2016-09-27 00:01:31 · 4965 阅读 · 0 评论 -
[JavaEE - JPA] 2. EJB中的事务管理
在上一篇文章中介绍了事务的基本概念,包括事务的ACID性质,以及事务的类型并且稍微提到了事务划分。对于任何一个需要持久化数据的应用而言,事务划分(Transaction Demarcation)的规划都是非常重要的一环。如果规划的不好,轻则影响性能,重则会导致在某些情况下数据发生不一致,从而严重影响业务逻辑的顺利进行。本文继续介绍事务划分在当前JavaEE技术体系下基于EJB的实现方案。虽然EJB算原创 2016-09-19 00:35:16 · 4855 阅读 · 0 评论 -
[JavaEE - JPA] 1. 事务的基础概念
现在任何应用都需要数据持久化。否则就不算是一个完整的应用。那么对于一个数据持久化而言,最重要的无外乎两方面:事务管理(Transaction Management)对象关系映射(Object Relational Mapping)本文作为JPA(Java Persistence API)这一系列文章的首篇,就来先谈谈事物管理相关的一些概念和基础。事务(Transaction, TX)事务管理,原创 2016-09-17 23:34:16 · 4335 阅读 · 1 评论 -
[Jackson] 使用ObjectMapper对含有任意key的JSON进行反序列化
使用ObjectMapper对含有任意key的JSON进行反序列化在调用某个RESTful API后,返回的JSON字符串中含有没有预先定义的key,和结构固定的JSON相比,它需要一些额外的操作。对于结构固定的JSON,使用ObjectMapper结合某个预先定义的实体类型可以非常方便地完成反序列化工作,比如对下面这样的JSON:GET /person/1{ "id": "1",原创 2015-07-05 17:42:49 · 46807 阅读 · 2 评论 -
[Java 8] (11) 使用Lambda的原则
要想更好的使用函数式编程,仅仅熟悉其语法结构是远远不够的。必须从思想和设计层面,去考虑它,去接纳它。这种编程范式和大多数开发人员所熟知的面向对象编程范式是不同的。下面我们从以下几个方面来回顾一下使用函数式编程的要点:多用声明式,少用命令式要想更好的使用函数式编程,首先必须要提升代码的抽象程度。之所以使用函数式编程在完成同样任务时需要的代码量比命令式要少,很大程度上就是源于函原创 2014-11-07 10:16:39 · 5826 阅读 · 1 评论 -
[Java 并发] Java并发编程实践 思维导图 - 第一章 简介
根据《Java并发编程实践》一书原创 2014-11-08 10:08:27 · 5002 阅读 · 1 评论 -
[AOP] 2. AOP的两种实现-Spring AOP以及AspectJ
在接触Spring以及种类繁多的Java框架时,很多开发人员(至少包括我)都会觉得注解是个很奇妙的存在,为什么加上了@Transactional之后,方法会在一个事务的上下文中被执行呢?为什么加上了@Cacheable之后,方法的返回值会被记录到缓存中,从而让下次的重复调用能够直接利用缓存的结果呢?随着对AOP的逐渐应用和了解,才明白注解只是一个表象,在幕后Spring AOP/AspectJ做了大原创 2017-02-26 22:29:18 · 22173 阅读 · 9 评论 -
[AOP] 4. Spring AOP中提供的种种Aspects - 异步执行
上一篇文章介绍了Spring AOP中提供的种种与Tracing相关的Aspects,还剩两个Aspects没有讨论:AsyncExecutionInterceptorConcurrencyThrottleInterceptor本文继续探讨和异步与并发相关一个Aspect,也是使用的比较普遍的一个:AsyncExecutionInterceptor在下篇文章中会继续讨论Concurrenc原创 2017-03-19 15:52:39 · 8003 阅读 · 0 评论 -
[AOP] 3. Spring AOP中提供的种种Aspects - Tracing相关
在第一篇文章中,介绍了AOP的一些背景知识以及如何快速上手,然后在第二篇中详细分析了AOP的两种实现 - Spring AOP以及AspectJ。本文偏向于实践,继续介绍Spring AOP中提供的种种Legacy Aspects。虽然这些Aspects的历史已经比较久远了(好多都是在Spring 1.x时代就存在了),但是并不妨碍我们理解它们背后蕴含的思想以及见识AOP能够解决的问题域。了解这些现原创 2017-03-11 17:32:48 · 8283 阅读 · 1 评论 -
JDK 8 函数式编程最佳实践
文章导航JDK 8 函数式编程最佳实践1. Lambda表达式的重要接口1.1 新增的函数接口1.1 无参数,无返回值类型接口1.2 无参数,有返回值类型接口1.3 有参数,也有返回值的类型接口2. 方法引用2.1 静态方法引用2.2 实例方法引用2.3 构造方法引用3. 使用Lambda表达式完成集合的规约操作3.1 成为一个单值类型3.2 成为一个集合类型3.3 stream和parallel...原创 2019-07-12 21:05:12 · 2000 阅读 · 0 评论 -
MCS锁的原理和实现
前情回顾上一篇文章中主要讨论了自旋锁的特点和其适用场景,然后给出了两种自旋锁的简单实现。存在的问题无论是简单的非公平自旋锁还是公平的基于排队的自旋锁,由于执行线程均在同一个共享变量上自旋,申请和释放锁的时候必须对该共享变量进行修改,这将导致所有参与排队自旋锁操作的处理器的缓存变得无效。如果排队自旋锁竞争比较激烈的话,频繁的缓存同步操作会导致繁重的系统总线和内存的流量,从而大大降低了...原创 2018-04-01 22:51:47 · 5343 阅读 · 5 评论 -
CLH锁的原理和实现
前情回顾上一篇文章中主要讨论了MCS自旋锁的特点和其适用场景,并分析了其原理和实现细节。MCS锁存在的问题MCS锁解决了简单自旋锁的一个最大痛点:频繁地缓存同步操作会导致繁重的系统总线和内存的流量,从而大大降低了系统整体的性能。解决这个问题的思路是将自旋操作限制在一个本地变量上,从而在根本上避免了频繁地多CPU之间的缓存同步。但是MCS锁的实现并不简单,需要注意的事项主要有以下...原创 2018-04-07 16:12:17 · 8599 阅读 · 3 评论 -
简单的非公平自旋锁以及基于排队的公平自旋锁的实现
基础什么是自旋锁由于本文主要讨论的都是自旋锁,所以首先就需要弄明白什么是自旋锁。自旋锁最大的特征,就是它会一直循环检测锁的状态,当锁处于被占用的状态时,不会将当前线程阻塞住,而是任由它继续消耗CPU Cycles,直到发现需要的锁处于可用状态。有了这一层了解,自旋锁的优势和劣势,以及其适用场景也就一目了然了。优势:没有线程阻塞,也就没有了线程上下文切换带来的开销...原创 2018-03-24 14:47:52 · 1588 阅读 · 0 评论 -
为什么volatile++不是原子性的?
问题在讨论原子性操作时,我们经常会听到一个说法:任意单个volatile变量的读写具有原子性,但是volatile++这种操作除外。所以问题就是:为什么volatile++不是原子性的?答案因为它实际上是三个操作组成的一个符合操作。首先获取volatile变量的值将该变量的值加1将该volatile变量的值写会到对应的主存地址一个很简单的例子:如果两个线程在...原创 2018-03-18 21:23:19 · 10677 阅读 · 9 评论 -
[Spring Boot] 5. Spring Boot中的ApplicationContext - 执行ApplicationContextInitializer初始化器
前面已经对Spring Boot启动过程进行过源码分析,对于代表容器上下文的关键字段ApplicationContext只是一笔带过。实际上,它的生命周期才应该是重点关注的。Spring Boot使用的ApplicationContext分两种场景,常规应用和Web应用使用的上下文类型不一样:常规应用:org.springframework.context.annotation.Annotatio原创 2017-08-27 12:50:17 · 17730 阅读 · 1 评论 -
[Spring Boot] 4. Spring Boot实现自动配置的原理
入口注解类@EnableAutoConfiguration@SpringBootApplication注解中包含了自动配置的入口注解:@Target(ElementType.TYPE)@Retention(RetentionPolicy.RUNTIME)@Documented@Inherited@SpringBootConfiguration@EnableAutoConfiguration原创 2017-08-27 12:44:17 · 15978 阅读 · 1 评论 -
[Spring Boot] 3. Spring Boot实现自动配置的基础
在第一篇文章介绍Spring Boot启动过程,提到了Spring Boot的核心能力 - 自动配置。这个能力也是Spring Boot非常大的卖点之一。对这个能力,相信很多同学都会比较好奇,Spring Boot是如何实现它的呢?但是在详细探究Spring Boot是如何实现自动配置之前,首先需要明确问题的来源是什么,以及了解目前Spring框架中提供的相关能力。引子问题是什么Spring中纷繁复原创 2017-08-20 23:00:20 · 4512 阅读 · 1 评论 -
[Spring Boot] 2. Spring Boot 启动过程定制化
在上一篇文章中,从源码角度介绍了Spring Boot的启动过程。启动的代码虽然只有短短的一行,但是背后所做的工作还真不少,其中有一些可以定制化的部分,主要分为以下几个方面:初始化器(Initializer)监听器(Listener)容器刷新后置Runners(ApplicationRunner或者CommandLineRunner接口的实现类)启动期间在Console打印Banner的具体原创 2017-08-13 22:45:21 · 6113 阅读 · 1 评论 -
[Spring Boot] 1. Spring Boot启动过程源码分析
关于Spring Boot,已经有很多介绍其如何使用的文章了,本文从源代码(基于Spring-boot 1.5.6)的角度来看看Spring Boot的启动过程到底是怎么样的,为何以往纷繁复杂的配置到如今可以这么简便。1. 入口类package com.example.demo;import org.springframework.boot.SpringApplication;import org原创 2017-08-05 21:25:54 · 26668 阅读 · 5 评论 -
[AOP] 7. 一些自定义的Aspect - Circuit Breaker
Circuit Breaker(断路器)模式关于断路器模式是在微服务架构/远程调用环境下经常被使用到的一个模式。它的作用一言以蔽之就是提高系统的可用性,在出现的问题通过服务降级的手段来保证系统的整体可用,而不至于因为部分问题导致整个系统不可用。用下面这张图可以很好的说明它能够解决的问题: 图片引用自参考资料1。其中从client和supplier可以分别理解成调用者和远程方法。在没有Circuit原创 2017-07-30 13:40:12 · 1368 阅读 · 0 评论 -
[AOP] 6. 一些自定义的Aspect - 方法的重试(Retry)
前面的一系列文章介绍了AOP的方方面面:AOP的由来以及快速上手AOP的两种实现-Spring AOP以及AspectJSpring AOP中提供的种种Aspects - Tracing相关Spring AOP中提供的种种Aspects - 异步执行Spring AOP中提供的种种Aspects - 并发控制从本篇文章开始,会介绍一些基于AOP原理的自定义Aspect实现,用来解决在开发原创 2017-06-03 12:01:10 · 3027 阅读 · 2 评论 -
[AOP] 5. Spring AOP中提供的种种Aspects - 并发控制
本文继续讨论ConcurrencyThrottleInterceptor(基于Spring 4.3.7)。以及上一篇文章中遗留的一个关于SimpleAsyncTaskExecutor类中属性concurrencyLimit的问题。这些都和并发控制相关。但是这里需要事先说明的一点是,这些类和实现的年代都比较久远了,比如ConcurrencyThrottleInterceptor是在2004年的Spri原创 2017-04-05 11:30:22 · 4899 阅读 · 0 评论 -
[Java 并发] Java并发编程实践 思维导图 - 第六章 任务执行
根据《Java并发编程实践》一书整理的思维导图。希望能够有所帮助。第一部分:第二部分:第三部分:原创 2014-11-28 09:08:29 · 5231 阅读 · 0 评论 -
[Java Performance] 数据库性能最佳实践 - JPA缓存
JPA缓存(JPA Caching)JPA有两种类型的缓存:EntityManager自身就是一种缓存。事务中从数据库获取的和写入到数据库的数据会被缓存(什么样的数据会被缓存,在后面有介绍)。在一个程序中也许会有很多个不同的EntityManager实例,每一个实例运行着不同的事务,拥有着它们自己的缓存。当EntityManager提交一个事务后,它缓存的所有数据就会被原创 2014-10-22 10:13:21 · 11782 阅读 · 1 评论 -
[Hibernate Search] (6) 高级查询 - 过滤,投影和分面
高级查询在介绍了更多的高级映射功能之后,是时候回顾一下之前介绍过的查询功能了,看看如何借助这些高级的映射功能来使用一些高级的查询功能。本文会通过以下几个方面进行介绍:如何在不和数据库进行任何交互的前提下,借助Lucene的力量来动态的筛选结果如何通过使用基于投影(Projection)的查询来获取需要的属性,从而避免与数据库的交互如何使用分面搜索(Faceted Search)对搜原创 2014-11-05 10:13:43 · 13157 阅读 · 1 评论 -
[Java 并发] Java并发编程实践 思维导图 - 第四章 对象的组合
[Java 并发] Java并发编程实践 思维导图 - 第四章 对象的组合。 整理的思维导图,希望对大家有所帮助。原创 2014-11-16 09:53:12 · 4929 阅读 · 0 评论 -
[Java 并发] Java并发编程实践 思维导图 - 第三章 对象的共享
根据《Java并发编程实践》一书整理的思维导图。原创 2014-11-13 10:11:22 · 5704 阅读 · 1 评论 -
[Java Performance] JVM 线程调优
调整线程栈空间当非常缺少内存时,可以调整线程使用的内存。每个线程都有一个栈,用来记录该线程的调用栈信息。线程中的栈的默认空间是有OS和JVM的版本决定的:OS32-bit64-bitLinux320 KB1 MBMac OSN/A1 MBSolaris Sparc512 KB1 MBSo原创 2014-10-10 18:09:18 · 5046 阅读 · 0 评论 -
[Java 并发] Java并发编程实践 思维导图 - 第二章 线程安全性
根据《Java并发编程实践》一书整理的思维导图。原创 2014-11-09 11:25:08 · 5324 阅读 · 0 评论 -
[Java Performance] Java集合API
Java集合APIJava 7提供了至少58个功能和实现各异的集合类型,在不同的场景下选择合适的集合类型十分重要。因为,程序的性能和集合类型的选择有莫大的关联。关于选择哪个集合类型,第一个需要考虑的就是程序使用的算法和操作方式。实际上这就是从数据结构的出发点来看问题,和使用的语言无关。比如,LinkedList不适合用在搜索操作较多的场合;如果需要以O(1)的开销从集合中得原创 2014-09-27 10:37:59 · 4001 阅读 · 0 评论 -
[Java Performance] 缓冲I/O(Buffered I/O)
缓冲I/O(Buffered I/O)InputStream.read()以及OutputStream.write()操作的对象是单个字节。根据它们访问的资源的不同,使用这些方法可能会相当慢。比如在使用FileInputStream.read()时,速度会慢的令人发指。因为每次调用都会访问操作系统的内核去拿到1个字节的数据。在现代的操作系统中,内核往往会使用缓冲I/O实现,因此这个原创 2014-09-25 23:08:03 · 4256 阅读 · 0 评论 -
[Java Performance] JIT编译器简介
使用JIT(Just-In-Time)编译器JIT编译器概览JIT编译器是JVM的核心。它对于程序性能的影响最大。CPU只能执行汇编代码或者二进制代码,所有程序都需要被翻译成它们,然后才能被CPU执行。C++以及Fortran这类编译型语言都会通过一个静态的编译器将程序编译成CPU相关的二进制代码。PHP以及Perl这列语言则是解释型语言,只需要安装正确的解释器,它们就能运行在原创 2014-09-24 22:07:28 · 10413 阅读 · 4 评论 -
[Java Performance] 字符串拼接注意事项
字符串拼接(String Concatenation)// 编译器优化前String answer = integerPart + "." + mantissa;// 编译器优化后String answer = new StringBuilder(integerPart).append(".").append(mantissa).toString();因为编译器会对字符串的原创 2014-09-26 12:32:53 · 4128 阅读 · 0 评论