⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 objectpool.java

📁 国外的一套开源CRM
💻 JAVA
📖 第 1 页 / 共 3 页
字号:
     * Sets the last used time for an object in the pool that is currently
     * in use.  If the timestamp parameter is not set, this call does nothing.
     * Otherwise, the object is marked as last used at the current time.
     * @throws java.lang.IllegalArgumentException
     *         Occurs when the object is not recognized by the factory or not
     *         in the pool.
     * @throws java.lang.IllegalStateException
     *         Occurs when the object is not currently in use.
     * @see #setTimestampUsed
     */
    public void setLastUsed(Object object) {
        if (!trackLastUsed) return;
        Object ob = null;
        try {
            ob = factory.translateObject(object);
        } catch (Exception e) {
            throw new IllegalArgumentException("Pool " + getName() + " does not recognize object for last used time: " + object);
        }
        ObjectRecord rec = ob == null ? null : (ObjectRecord) objects.get(ob);
        if (rec == null)
            throw new IllegalArgumentException("Pool " + getName() + " does not recognize object for last used time: " + object);
        if (rec.isInUse())
            rec.setLastUsed();
        else
            throw new IllegalStateException("Cannot set last updated time for an object that's not in use!");
    }

    /**
     * Indicates that an object is no longer valid, and should be removed from
     * the pool entirely.  This should be called before the object is returned
     * to the pool (specifically, before factory.returnObject returns), or else
     * the object may be given out again by the time this is called!  Also, you
     * still need to actually return the object to the pool by calling
     * releaseObject, if you aren't calling this during that process already.
     * @param object The object to invalidate, which must be the exact object
     *               returned by getObject
     */
    public void markObjectAsInvalid(Object object) {
        if (deadObjects == null)
            throw new IllegalStateException("Tried to use pool before it was Initialized or after it was ShutDown!");
        deadObjects.add(object); //a synchronized set

    }

    /**
     * Returns an object to the pool.  This must be the exact object that was
     * given out by getObject, and it must be returned to the same pool that
     * generated it.  If other clients are blocked waiting on an object, the
     * object may be re-released immediately.
     * @throws java.lang.IllegalArgumentException
     *    Occurs when the object is not in this pool.
     */
    public void releaseObject(Object object) {

        log.debug("Pool " + this + " object released: " + object);

        Object pooled = null;
        try {
            factory.returnObject(object);//do this first
            pooled = factory.translateObject(object);
        } catch (Exception e) {
            return;        // We can't release it if the factory can't recognize it
        }
        if (pooled == null) // We can't release it if the factory can't recognize it
            return;
        boolean removed = false;
        synchronized (objects) {
            ObjectRecord rec = (ObjectRecord) objects.get(pooled);
            if (rec == null) // Factory understands it, but we don't
                throw new IllegalArgumentException("Object " + object + " is not in pool " + poolName + "!");
            if (!rec.isInUse()) return; // Must have been released by GC?
            if (object instanceof PooledObject)
                ((PooledObject) object).removePoolEventListener(this);
            removed = deadObjects.remove(object);
            rec.setInUse(false);
            if (removed) {
                log.debug("Object was dead: " + object);
                objects.remove(pooled);
                rec.close();
            } // end of if ()

        }//end of synch on objects
        if (removed) {
            try {
                factory.deleteObject(pooled);
            } catch (Exception e) {
                log.error("Pool " + this + " factory (" + factory.getClass().getName() + " delete error: ", e);
            }
            fillToMin();
            /*FIXME --MINSIZE
              if(objects.size() < minSize)
              createNewObject(null);
            */
        }

        if (removed)
            log.debug("Pool " + this + " destroyed object " + object + ".");
        else
            log.debug("Pool " + this + " returned object " + object + " to the pool.");

        permits.release();
        /*
        if(blocking)
        {
           synchronized(this)
           {
              notify();
           }
        }
        */
    }

    private int getUsedCount() {
        int total = 0;
        synchronized (objects) {
            for (Iterator it = new HashSet(objects.values()).iterator(); it.hasNext();) {
                ObjectRecord or = (ObjectRecord) it.next();
                if (or != null && or.isInUse())
                    ++total;
            }
        }
        return total;
    }

    /**
     * Returns the pool name and status.
     */
    public String toString() {
        return poolName + " [" + getUsedCount() + "/" + (objects == null ? 0 : objects.size()) + "/" + (maxSize == 0 ? "Unlimited" : Integer.toString(maxSize)) + "]";
    }


    // ---- PoolEventListener Implementation ----

    /**
     * If the object has been closed, release it.
     */
    public void objectClosed(PoolEvent evt) {
        releaseObject(evt.getSource());
    }

    /**
     * If the invalidateOnError flag is set, the object will be removed from
     * the pool entirely when the client has finished with it.
     */
    public void objectError(PoolEvent evt) {
        if (invalidateOnError || evt.isCatastrophic())
            markObjectAsInvalid(evt.getSource());
    }

    /**
     * If we're tracking the last used times, update the last used time for the
     * specified object.
     */
    public void objectUsed(PoolEvent evt) {
        if (!trackLastUsed) return;
        setLastUsed(evt.getSource());
    }

    long getNextGCMillis(long now) {
        long t = lastGC + gcIntervalMillis - now;

        log.debug("getNextGCMillis(): returning " + t);

        if (!runGC)
            return Long.MAX_VALUE;

        return t;
    }

    // Allow GC if we're within 10% of the desired interval
    boolean isTimeToGC() {
        long now;
        now = System.currentTimeMillis();

        log.debug("isTimeToGC(): " + (now >= lastGC + Math.round((float) gcIntervalMillis * 0.9f)));

        return now >= lastGC + Math.round((float) gcIntervalMillis * 0.9f);

    }

    void runGCandShrink() {

        log.debug("runGCandShrink(): runGC = " + runGC + "; idleTimeout = " + idleTimeout);

        if (runGC || idleTimeout) {
            HashSet objsCopy;
            synchronized (objects) {
                objsCopy = new HashSet(objects.values());
            }

            if (runGC) { // Garbage collection - return any object that's been out too long with no use
                Iterator it = objsCopy.iterator();
                while (it.hasNext()) {
                    ObjectRecord rec = (ObjectRecord) it.next();
                    if (rec != null && rec.isInUse() && rec.getMillisSinceLastUse() >= gcMinIdleMillis) {
                        releaseObject(rec.getClientObject());
                    }
                }
            }
            if (idleTimeout) { // Shrinking the pool - remove objects from the pool if they have not been used in a long time
                // Find object eligible for removal
                HashSet eligible = new HashSet();
                Iterator it = objsCopy.iterator();
                while (it.hasNext()) {
                    ObjectRecord rec = (ObjectRecord) it.next();
                    if (rec != null && !rec.isInUse() && rec.getMillisSinceLastUse() > idleTimeoutMillis)
                        eligible.add(rec);
                }
                // Calculate max number of objects to remove without replacing
                int max = Math.round(eligible.size() * maxIdleShrinkPercent);
                if (max == 0 && eligible.size() > 0) max = 1;
                int count = 0;
                // Attempt to remove that many objects
                it = eligible.iterator();
                while (it.hasNext()) {
                    try {
                        // Delete the object
                        ObjectRecord rec = (ObjectRecord) it.next();
                        if (rec != null) {
                            rec.setInUse(true);  // Don't let someone use it while we destroy it
                            Object pooled = rec.getObject();
                            synchronized (objects) {
                                objects.remove(pooled);
                            }
                            //removeObject(pooled);
                            try {
                                factory.deleteObject(pooled);
                            } catch (Exception e) {
                                log.error("Pool " + this + " factory (" + factory.getClass().getName() + " delete error: ", e);
                            }
                            rec.close();
                            ++count;
                        }
                        fillToMin();
                        /*FIXME --MINSIZE
                                    if(count > max || objects.size() < minSize)
                                       createNewObject(null);

                        */
                    } catch (ConcurrentModificationException e) {
                    }
                }
            }
        }
        lastGC = System.currentTimeMillis();
    }

    /**
     * Removes an object from the pool.  Only one thread can add or remove
     * an object at a time.
     */
    /*   private void removeObject(Object pooled)
    {
       synchronized(objects)
       {
          objects.remove(pooled);
       }
    }
    */
    /**
     * Creates a new Object.
     * @param parameters If <b>true</b>, then the object is locked and
     *          translated by the factory, and the resulting object
     *          returned.  If <b>false</b>, then the object is left in the
     *          pool unlocked.
     */
    private ObjectRecord createNewObject(Object parameters) {
        Object ob = null;
        try {
            ob = factory.createObject(parameters);
        } catch (Exception ex) {
            throw new RuntimeException("Could not create connection");
        }
        if (ob != null) { // if factory can create object
            ObjectRecord rec = new ObjectRecord(ob);
            synchronized (objects) {
                objects.put(ob, rec);
            }
            return rec;
        } else {
            throw new RuntimeException("could not create new object!");
        }
    }

    public void fillToMin() {
        Collection newMCs = new ArrayList();
        try {
            while (objects.size() < minSize) {
                newMCs.add(getObject(null));
            } // end of while ()
        } catch (Exception re) {
            //Whatever the reason, stop trying to add more!
        } // end of try-catch
        for (Iterator i = newMCs.iterator(); i.hasNext();) {
            releaseObject(i.next());
        } // end of for ()

    }

}

class BeanFactory extends PoolObjectFactory {

    private Class beanClass;

    private Logger log = Logger.getLogger(BeanFactory.class);

    public BeanFactory(Class beanClass) {
        try {
            beanClass.getConstructor(new Class[0]);
        } catch (NoSuchMethodException e) {
            throw new IllegalArgumentException("Bean class doesn't have no-arg constructor!");
        }
        this.beanClass = beanClass;
    }

    public void poolStarted(ObjectPool pool) {
        super.poolStarted(pool);
    }

    public Object createObject(Object parameters) {
        try {
            return beanClass.newInstance();
        } catch (Exception e) {
            log.error("Unable to create instance of " + beanClass.getName(), e);
        }
        return null;
    }
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -