Jedis

transient,序列化(serializaion)的时候不会讲带有此关键字的变量序列化

static class静态内部类:

非static的inner class中不可声明static变量和方法

非static的inner class可以随意的应用非static的outer class的非static变量和方法,static class只能引用static方法和变量

创建static inner class的时候不需要将其实例绑定到outer class实例上

 

Throwable是java.lang.Error和java.lang.Exception的父类

 

JedisPool继承了Pool<T>类,最原始的Pool类,仅仅对GenericObjectPool进行了一层简单的封装,将borrowObject,returnObject,returnInvalidateObject简单封装了下

JedisPool自己定义了private类JedisFactory,也仅仅是对BasePoolalbeObjectFactory的简单封装,实现了makeObject,destroyObject,validateObject,分别 new一个jedis并且connect了,disconnect一个jedis,

 

jedis继承了BinaryJedis,BinaryJedis里面放了一个Client,继承自BinaryClient,

 

apache-commons-pool

        switch(whenExhaustedAction) {
            case WHEN_EXHAUSTED_BLOCK:
            case WHEN_EXHAUSTED_FAIL:
            case WHEN_EXHAUSTED_GROW:
                _whenExhaustedAction = whenExhaustedAction;
                break;
            default:
                throw new IllegalArgumentException("whenExhaustedAction " + whenExhaustedAction + " not recognized.");
        }

技巧

 

_pool = new CursorableLinkedList();
startEvictor(_timeBetweenEvictionRunsMillis);

 CursorableLinkedList是可serialize的,主要如其名字,也是一个在内存中的链表,没有任何同步机制和锁机制

主要方法是insertListable,生成一个inner class的Listable对象,然后broadcastListaleInserted

Listable就是一个双向链表的节点(node)

Cursor是CursorableLinkedList的inner class,主要继承了ListIter

 

 

GenericObjectPool继承了BaseObjectPool这个抽象类和ObjectPool这个接口

主要的几个方法:

borrowObject

1. synchronized(this)block

2. 根据_whenExhaustedAction,确定当pool已经没有更多的对象时,对象池的行为

LinkedList::add,将一个元素加到这个链表尾部

3. makeObject

4. activate & validate object

 

latch:控制allocation顺序以保证公平性,即,threads获得objects,以其request的先后顺序

 

 

_allocationQueue:一个linkedList。用于追踪threads call,所以objects可以以threads的request顺序被allocated

private synchronized void allocate():一个核心方法

1. 如果_pool或者_allocationQueue都不为空,则_allocationQueue.removeFirst的latch,_pool.removeFirst

2. 如果_pool先为空,_allocationQueue不为空且活动对象小于maxActive,那么,_allocationQueue.removeFirst,并且置位mayCreate,可以创造新的object

 

还有一个Evictor类实现一部分LRUCache的功能

 

maxIdle:在pool中可存在的最多的对象数目

maxActive:等待被使用和已经被使用的Object数目

/**
* The number of objects subject to some form of internal processing
* (usually creation or destruction) that should be included in the total
* number of objects but are neither active nor idle.
*/
private int _numInternalProcessing = 0;

 

addObject: factory.makeObject,然后调用addObjectToPool,然后allocate

returnObject:直接addObjectToPool

borrowObject:这是逻辑最复杂的地方,也直接的用到很多锁synchronized(this),控制对象池消耗空后的行为也由它负责,其block是由latch.wait()实现的,GenericObjectPool的所有wait都是由latch发起的

 

1. synchronized(this),_allocationQueue.add(new latch()),allocate(): allocate

allocate的核心想法是保持maxActive的数目,如果pool和allocationQueue中存在Object,就把他们释放出来

latch承担了核心的multithreading的同步功能。控制block时候的pool行为

allocate相当于一个释放过程,把pool和allocationQueue中的对象都释放出来

    /**
     * Allocate available instances to latches in the allocation queue.  Then
     * set _mayCreate to true for as many additional latches remaining in queue
     * as _maxActive allows.
     */
  /*
  这个allocate在我看来有两个功能,就是把应该释放出去的Object全部放出去。第一个for循环,将所有在池中的对象释放出去,因为已经换存在池中,所以不需要建立新的对象
而在底下不在池中的对象就需要重新建立

Problem:
这个api的问题很大。synchronized就相当于对一个GenericObjectPool对象进行锁,会极大的拖慢速度
  */
private synchronized void allocate() { if (isClosed()) return; // First use any objects in the pool to clear the queue for (;;) { if (!_pool.isEmpty() && !_allocationQueue.isEmpty()) { Latch latch = (Latch) _allocationQueue.removeFirst(); latch.setPair((ObjectTimestampPair) _pool.removeFirst()); _numInternalProcessing++; synchronized (latch) { latch.notify(); } } else { break; } } // Second utilise any spare capacity to create new objects for(;;) { if((!_allocationQueue.isEmpty()) && (_maxActive < 0 || (_numActive + _numInternalProcessing) < _maxActive)) { Latch latch = (Latch) _allocationQueue.removeFirst(); latch.setMayCreate(true); _numInternalProcessing++; synchronized (latch) { latch.notify(); } } else { break; } } }

 

Allocate available instances to latches in the allocation queue. Then
* set _mayCreate to true for as many additional latches remaining in queue
* as _maxActive allows.

  

2. for的永久循环中进行了对exhaustion的行为的判断

addObjectToPool:这边才是真正提供同步的地方。一个synchronized(this)提供了针对这个instance的intrinsic lock,Object都存在CursorableLinkedList

posted on 2014-02-19 18:01  starfuxks  阅读(775)  评论(0)    收藏  举报

导航