mybatis源码分析一

我们从最简单的一段代码开始,分析清楚mybatis的大致工作流程。然后再从代码细节上分析mybatis的一些特性。 基础代码示例1234567891011121314151617public class test { public static void main(String[] args) throws IOException{ String resource = "example/mybatis-config.xml"; // 加载配置文件 并构建SqlSessionFactory对象 InputStream inputStream = Resources.getResourceAsStream(resource); SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(inputStream); // 从SqlSessionFactory对象中获取 SqlSession对象 SqlSession sqlSession = factory.openSession(); // 执行操作 User user=new User(); user.setId(1); Object u= (User)sqlSession.selectOne("getUser", user); System.out.println(u.toString()); // 关闭SqlSession sqlSession.close(); }}

CyclicBarrier源码分析

概述CyclicBarrier是一个同步辅助类,它允许一组线程相互等待,直到达到某个公共屏障点。并且在释放等待线程之后,CyclicBarrier是可以重复使用的。

CountDownLatch源码分析

概述CountDownLatch允许一个或多个线程等待直到在其他线程中执行的一组操作完成的同步辅助。简单来说,就是CountDownLatch内部维护了一个计数器,每个线程完成自己的操作之后都会将计数器减一,然后会在计数器的值变为0之前一直阻塞,直到计数器的值变为0.

ReentrantReadWriteLock源码分析

概述ReentrantReadWriteLock维护了一对相关的锁,它们分别是共享readLock和独占writeLock。关于共享读锁和排他写锁的概念其实很好理解。所谓共享读锁就是一个线程读的时候,其它线程也可以来读(共享),但是不能来写。排他写锁是指一个线程在写的时候,其它线程不能来写或读(排他)。除了这个特点之外,ReentrantReadWriteLock还有一个特点就是可重入的。它和ReentrantLock一样都是支持Condition的。而且ReentrantReadWerite还支持锁降级,即允许将写锁降级为读锁。

ReentrantLock源码分析

概述ReentrantLock是一个可重入的互斥锁,也被称为独占锁。它支持公平锁和非公平锁两种模式。

AQS基本原理

什么是AQS?AQS即AbstractQueuedSynchronizer,是一个用于构建锁和同步器的框架。它能降低构建锁和同步器的工作量,还可以避免处理多个位置上发生的竞争问题。在基于AQS构建的同步器中,只可能在一个时刻发生阻塞,从而降低上下文切换的开销,并提高吞吐量。

HashSet源码分析

概览123public class HashSet<E> extends AbstractSet<E> implements Set<E>, Cloneable, java.io.Serializable 值得注意的是HashSet底层是基于HashMap来实现的。HashSet是一个集合,集合是没有重复的元素的,不能保证顺序的。而且HashSet是非同步的。它的继承体系如下 属性1234private transient HashMap<E,Object> map;private static final Object PRESENT = new Object();

HashMap源码分析

概览12public class HashMap<K,V> extends AbstractMap<K,V> implements Map<K,V>, Cloneable, Serializable { 从继承关系上看好像并不没有什么特点。它基于哈希表实现了Map接口,并且允许null的值和null的键。HashMap并不能保证有序性。并且它不是同步的。 [] 属性分析1static final int DEFAULT_INITIAL_CAPACITY = 1 << 4; 默认的初始容量为16.初始容量的大小和负载因子是非常影响其性能的两个参数。 1static final int MAXIMUM_CAPACITY = 1 << 30; 最大的允许的容量 1static final float DEFAULT_LOAD_FACTOR = 0.75f; 默认的负载因子(装填因子)。这是一个非常重要的参数。负载因子的定义为:填入表中的元素的个数/哈希表的长度(桶的个数)。所以装填因子越大产生冲突的可能性也越大。简单的来说就是装的越多其装满程度也越大,其装填因子也就越大。

LinkedList源码分析

概览123public class LinkedList<E> extends AbstractSequentialList<E> implements List<E>, Deque<E>, Cloneable, java.io.Serializable 值得注意的时LinkedList除了实现了List还实现了Deque.也就是说LinkedList也可以当作队列来使用。LinkedList的底层是基于双向链表来实现的。所以它不支持随机访问,但也正是因为采用了双向链表实现,所以它有很高的插入和删除效率。 属性分析1transient int size = 0; size记录了链表中有效元素的个数。 12transient Node<E> first;transient Node<E> last; 双向链表的头指针和尾指针。这里有一个需要注意的地方,他们都使用了transient修饰,也就是说,他们不会被序列化。那么反序列化的时候怎么知道链表头和链表尾呢?其实在序列化的时候,只将链表本身和size进行了序列化,在反序列化的时候,首先获得size的值(此时firse和last为null),然后再将Node一个个读取出来,使用linkLast(E e)重构整个链表。而在这个方法中完成了first和last的赋值。

Vector源码分析

概览123public class Vector<E> extends AbstractList<E> implements List<E>, RandomAccess, Cloneable, java.io.Serializable Vector和ArrayList非常的相似,两者都是基于数组实现的。两者最大的不同在于Vector是线程安全的。Vector为了确保线程安全,使用了大量的synchronized方法,这也使得Vector的性能较差。 属性解释1protected Object[] elementData; 和ArrayList类似,使用了数组来作为容器,但和ArrayList不同的是,它并没有transient 修饰,也就是说在序列化时,它也会被序列化。 1protected int elementCount; elementCount记录了Vector对象中存储的有效对象的数量。在创建Vector对象的时候如果没有指明大小的话,默认的大小为10. 1protected int capacityIncrement; capacityIncrement记录了每次扩容时增加的容量大小。如果在创建Vector对象时指定了capacityIncrement的大小,那么每次扩容增加的大小就为:capacityIncrement。如果在创建的时候,没有指定capacityIncrement的大小,那么每次扩容就会扩大两倍。这和ArrayList有些许的不同。

123