0%

1. 简介

本篇文章是上一篇文章(创建单例 bean 的过程)的延续。在上一篇文章中,我们从战略层面上领略了doCreateBean方法的全过程。本篇文章,我们就从战术的层面上,详细分析doCreateBean方法中的一个重要的调用,即createBeanInstance方法。在本篇文章中,你将看到三种不同的构造 bean 对象的方式。你也会了解到构造 bean 对象的两种策略。如果你对这些内容感兴趣,那么不妨继续往下读。我会在代码进行大量的注解,相信能帮助你理解代码逻辑。好了,其他的就不多说了,进入正题吧。

阅读全文 »

1. 简介

上一篇文章中,我比较详细的分析了获取 bean 的方法,也就是getBean(String)的实现逻辑。对于已实例化好的单例 bean,getBean(String) 方法并不会再一次去创建,而是从缓存中获取。如果某个 bean 还未实例化,这个时候就无法命中缓存。此时,就要根据 bean 的配置信息去创建这个 bean 了。相较于getBean(String)方法的实现逻辑,创建 bean 的方法createBean(String, RootBeanDefinition, Object[])及其所调用的方法逻辑上更为复杂一些。关于创建 bean 实例的过程,我将会分几篇文章进行分析。本篇文章会先从大体上分析 createBean(String, RootBeanDefinition, Object[])方法的代码逻辑,至于其所调用的方法将会在随后的文章中进行分析。

阅读全文 »

1. 简介

为了写 Spring IOC 容器源码分析系列的文章,我特地写了一篇 Spring IOC 容器的导读文章。在导读一文中,我介绍了 Spring 的一些特性以及阅读 Spring 源码的一些建议。在做完必要的准备工作后,从本文开始,正式开始进入源码分析的阶段。

在本篇文章中,我将会详细分析BeanFactorygetBean(String)方法实现细节,getBean(String) 及所调用的方法总体来说实现上较为复杂,代码长度比较长。作为源码分析文章,本文的文章长度也会比较长,希望大家耐心读下去。

阅读全文 »

1. 简介

Spring 是一个轻量级的企业级应用开发框架,于 2004 年由 Rod Johnson 发布了 1.0 版本。经过十几年的迭代,现在的 Spring 框架已经非常成熟了。Spring 包含了众多模块,包括但不限于 Core、Bean、Context、AOP 和 Web 等。在今天,我们完全可以使用 Spring 所提供的一站式解决方案开发出我们所需要的应用。作为 Java 程序员,我们会经常和 Spring 框架打交道,所以还是很有必要弄懂 Spring 的原理。

阅读全文 »

1.简介

CAS 全称是 compare and swap,是一种用于在多线程环境下实现同步功能的机制。CAS 操作包含三个操作数 – 内存位置、预期数值和新值。CAS 的实现逻辑是将内存位置处的数值与预期数值想比较,若相等,则将内存位置处的值替换为新值。若不相等,则不做任何操作。

在 Java 中,Java 并没有直接实现 CAS,CAS 相关的实现是通过 C++ 内联汇编的形式实现的。Java 代码需通过 JNI 才能调用。关于实现上的细节,我将会在第3章进行分析。

前面说了 CAS 操作的流程,并不是很难。但仅有上面的说明还不够,接下来我将会再介绍一点其他的背景知识。有这些背景知识,才能更好的理解后续的内容。

阅读全文 »

1.简介

在分析完AbstractQueuedSynchronizer(以下简称 AQS)和ReentrantLock的原理后,本文将分析 java.util.concurrent 包下的两个线程同步组件CountDownLatchCyclicBarrier。这两个同步组件比较常用,也经常被放在一起对比。通过分析这两个同步组件,可使我们对 Java 线程间协同有更深入的了解。同时通过分析其原理,也可使我们做到知其然,并知其所以然。

阅读全文 »

1.简介

可重入锁ReentrantLock自 JDK 1.5 被引入,功能上与synchronized关键字类似。所谓的可重入是指,线程可对同一把锁进行重复加锁,而不会被阻塞住,这样可避免死锁的产生。ReentrantLock 的主要功能和 synchronized 关键字一致,均是用于多线程的同步。但除此之外,ReentrantLock 在功能上比 synchronized 更为丰富。比如 ReentrantLock 在加锁期间,可响应中断,可设置超时等。

ReentrantLock 是我们日常使用很频繁的一种锁,所以在使用之余,我们也应该去了解一下它的内部实现原理。ReentrantLock 内部是基于 AbstractQueuedSynchronizer(以下简称AQS)实现的。所以要想理解 ReentrantLock,应先去 AQS 相关原理。我在之前的文章 AbstractQueuedSynchronizer 原理分析 - 独占/共享模式 中,已经详细分析过 AQS 原理,有兴趣的朋友可以去看看。本文仅会在需要的时候对 AQS 相关原理进行简要说明,更详细的说明请参考我的其他文章。

阅读全文 »

1. 简介

Condition是一个接口,AbstractQueuedSynchronizer 中的ConditionObject内部类实现了这个接口。Condition声明了一组等待/通知的方法,这些方法的功能与Object中的wait/notify/notifyAll等方法相似。这两者相同的地方在于,它们所提供的等待/通知方法均是为了协同线程的运行秩序。只不过,Object 中的方法需要配合 synchronized 关键字使用,而 Condition 中的方法则要配合锁对象使用,并通过newCondition方法获取实现类对象。除此之外,Condition 接口中声明的方法功能上更为丰富一些。比如,Condition 声明了具有不响应中断和超时功能的等待接口,这些都是 Object wait 方法所不具备的。

阅读全文 »

1.简介

AbstractQueuedSynchronizer (抽象队列同步器,以下简称 AQS)出现在 JDK 1.5 中,由大师 Doug Lea 所创作。AQS 是很多同步器的基础框架,比如 ReentrantLock、CountDownLatch 和 Semaphore 等都是基于 AQS 实现的。除此之外,我们还可以基于 AQS,定制出我们所需要的同步器。

AQS 的使用方式通常都是通过内部类继承 AQS 实现同步功能,通过继承 AQS,可以简化同步器的实现。如前面所说,AQS 是很多同步器实现的基础框架。弄懂 AQS 对理解 Java 并发包里的组件大有裨益,这也是我学习 AQS 并写出这篇文章的缘由。另外,需要说明的是,AQS 本身并不是很好理解,细节很多。在看的过程中药有一定的耐心,做好看多遍的准备。好了,其他的就不多说了,开始进入正题吧。

阅读全文 »

1.简介

线程池可以简单看做是一组线程的集合,通过使用线程池,我们可以方便的复用线程,避免了频繁创建和销毁线程所带来的开销。在应用上,线程池可应用在后端相关服务中。比如 Web 服务器,数据库服务器等。以 Web 服务器为例,假如 Web 服务器会收到大量短时的 HTTP 请求,如果此时我们简单的为每个 HTTP 请求创建一个处理线程,那么服务器的资源将会很快被耗尽。当然我们也可以自己去管理并复用已创建的线程,以限制资源的消耗量,但这样会使用程序的逻辑变复杂。好在,幸运的是,我们不必那样做。在 JDK 1.5 中,官方已经提供了强大的线程池工具类。通过使用这些工具类,我们可以用低廉的代价使用多线程技术。

阅读全文 »