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

📄 resourcedispatcher.java

📁 JXTA&#8482 is a set of open, generalized peer-to-peer (P2P) protocols that allow any networked devi
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
                long res = holdExtra(toAsk);                if (res != toAsk) {                    // Could not get enough. We got nothing.                    releaseExtra(res);                    return false;                }            }                        // Now record it.            nbReserved -= quantity;                        if (Logging.SHOW_SEVERE && LOG.isLoggable(Level.SEVERE)) {                if (nbReserved > fromReservedItems + fromExtraItems) {                    LOG.severe("Incorrect values after obtaining " + quantity + " : [" + this + "]");                }            }                        return true;        }                /**         * {@inheritDoc}         */        public boolean obtainItem() {                        // Set it for consistency. It will get cleared when            // the item is used to satisfy the need.            needs = true;                        if (nbReserved > 0) {                notEligible();                --nbReserved;                return true; // Its pre-reserved.            }                        // This account may deliberately limit the number of extra            // items it uses. this translates into a lower limit for            // nbReserved when <= 0.            if (nbReserved <= extraLimit) {                notEligible();                return false;            }                        if (holdExtra(1) == 1) { // Need authorization.                notEligible();                --nbReserved;                return true;            }                        // We are out of luck but eligible.            beEligible();            return false;        }                /**         * {@inheritDoc}         */        public void releaseQuantity(long quantity) {            if (nbReserved < 0) {                releaseExtra(quantity < -nbReserved ? quantity : -nbReserved);            }            nbReserved += quantity;            if (Logging.SHOW_SEVERE && LOG.isLoggable(Level.SEVERE)) {                if (nbReserved > fromReservedItems + fromExtraItems) {                    LOG.severe("Incorrect values after releasing " + quantity + " : [" + this + "]");                }            }        }                /**         *  {@inheritDoc}         */        public ResourceAccount releaseItem() {            if (nbReserved < 0) {                if (eligibles == null) {                    // RoundRobin is OFF either we reuse it or we let                    // it go.                    if (needs) {                        return this;                    }                                        ++nbReserved;                    releaseExtra(1);                    return null;                }                                // RoundRobin is ON, we compete with others for this item.                ++nbReserved;                                // Update our eligibility which depends on extraLimit and                // whether we have a use for the item or not.                if ((nbReserved > extraLimit) && needs) {                    beEligible();                }                                ClientAccount next = mostEligible();                                if (next == null) {                    releaseExtra(1); // noone wants it. return to main pool                } else {                    next.granted();                }                return next;            }                        // Since we are (back) in our reserved range, we can't be eligible            // for extra.            notEligible();                        // In reserved range; we keep using the item if we need it.            if (needs) {                return this;            }                        ++nbReserved;            return null;        }                /**         *  {@inheritDoc}         */        public void inNeed(boolean needs) {            this.needs = needs;            if ((nbReserved < 0) && (nbReserved > extraLimit) && needs) {                beEligible();            } else {                notEligible();            }        }                /**         *  {@inheritDoc}         */        public Object getUserObject() {            return userObject;        }                /**         *  {@inheritDoc}         */        public void setUserObject(Object object) {            userObject = object;        }                /**         *  {@inheritDoc}         */        public long getNbReserved() {            return nbReserved;        }                /**         *  {@inheritDoc}         *         *  <p/>Returns some human-readable status and identity information useful for debugging.         */        @Override        public String toString() {            return super.toString() + " : needs=" + needs + " nbReserved=" + nbReserved + " fromReservedItems="                    + fromReservedItems + " fromExtraItems=" + fromExtraItems + " extraLimit=" + extraLimit;        }            }        /**     * The list of eligible accounts.     */    private Dlist eligibles;        /**     * Construct a Fair Resource Allocator with the given parameters:     * @param minAccounts The minimum number of client accounts that we want to     * guarantee we can handle. <0 means 0     *     * @param minReservedPerAccount The minimum reservation request that we will     * always grant to accounts as long as we have less than minAccounts <0 means     * 0.     * @param maxReservedPerAccount The maximum reservation request that we ever     * will grant to any given account. <minReservedPerAccount means ==     * @param extraItems The total number of items that we will authorize     * beyond what has been reserved. <0 means 0.     * @param maxExtraPerAccount The maximum number of extra items we will ever     * let any given account occupy. <0 or >extraItems means ==extraItems.     * @param minExtraPoolSize The number of extra items that can never be     * taken out of the extra pool to satisfy a reservation request.     * @param roundRobin If true, when there is no items available, all     * eligible accounts are put in a FIFO. Accounts release items often, and the     * oldest account in the FIFO will get it. If false, accounts always keep     * items for as long as they can use them, and there is no FIFO of eligible     * accounts. Accounts can obtain new resources only if available at the time     * they try to aquire it. RoundRobin is more fair but has more overhead.     * Neither mode will cause starvation as long as accounts reserve at least     * one item each. RoundRobin is most useful when allocating threads.     */    public ResourceDispatcher(long minAccounts, long minReservedPerAccount, long maxReservedPerAccount, long extraItems, long maxExtraPerAccount, long minExtraPoolSize, boolean roundRobin, String dispatcherName) {        if (minAccounts < 0) {            minAccounts = 0;        }        if (minReservedPerAccount < 0) {            minReservedPerAccount = 0;        }        if (maxReservedPerAccount < minReservedPerAccount) {            maxReservedPerAccount = minReservedPerAccount;        }        if (extraItems < 0) {            extraItems = 0;        }        if (minExtraPoolSize < 0) {            minExtraPoolSize = 0;        }                if ((maxExtraPerAccount < 0) || (maxExtraPerAccount > extraItems)) {            maxExtraPerAccount = extraItems;        }                this.extraItems = extraItems;        this.minExtraPoolSize = minExtraPoolSize;        this.maxReservedPerAccount = maxReservedPerAccount;        this.minReservedPerAccount = minReservedPerAccount;        this.reservedItems = minAccounts * minReservedPerAccount;        this.maxExtraPerAccount = maxExtraPerAccount;        nbEligibles = 0;        if (roundRobin) {            eligibles = new Dlist();        }                this.myName = dispatcherName;    }        private long holdReserved(long req) {        if (req > reservedItems) {            req = reservedItems;        }        reservedItems -= req;        return req;    }        private void releaseReserved(long nb) {        reservedItems += nb;    }        private long holdExtra(long req) {        if (req > extraItems) {            req = extraItems;        }        extraItems -= req;        return req;    }        // Get items from the extra pool but only if there is at least    // minExtraPoolSize item    // left after that. The goal is to make sure we keep at least one    // un-reserved item when granting reserved items from the extra pool.    // Thanks to that, even accounts that could not get a single reserved    // item still stand a chance to make progress by taking turns using    // the one extra item left.    private long holdExtraKeepSome(long req) {        if (extraItems <= minExtraPoolSize) {            return 0;        }        long allowed = extraItems - minExtraPoolSize;        if (req > allowed) {            req = allowed;        }        extraItems -= req;        return req;    }        private void releaseExtra(long nb) {        extraItems += nb;    }        private void newEligible(ClientAccount account) {        ++nbEligibles;        eligibles.putLast(account);    }        private ClientAccount mostEligible() {        if (nbEligibles == 0) {            return null;        }        return (ClientAccount) eligibles.getFirst();    }        private void unEligible(ClientAccount account) {        --nbEligibles;        account.unlink();    }        // Not synch; it's just a snapshot for trace purposes.    public int getNbEligibles() {        return nbEligibles;    }        /**     * Creates and returns a new client account.     *     * @param nbReq the number of reserved items requested (may not be     * always granted in full). A negative value is taken to mean 0.     * @param maxExtra the number of additional items that this account     * authorizes to be allocated in addition to the reserved ones. This     * is typically useful if the items are threads and if some accounts     * are not re-entrant. Then nbReq would be 1 and maxExtra would be 0.     * It is also permitted to have some accounts receive no items at all     * ever by setting nbReq and maxExtra both to zero. A negative maxExtra     * is taken as meaning no specified limit, in which case an actual limit     * may be set silently.     * @param userObject An opaque cookie that the account object will return     * when requested. This is useful to relate an account returned by     * ClientAccount.releaseItem() to an invoking code relevant object.     * @return ResourceAccount An account with this allocator.     */    public ResourceAccount newAccount(long nbReq, long maxExtra, Object userObject) {                long extra = 0; // reserved from extra pool        long reserved = 0; // reserved from reserved pool                if (nbReq > maxReservedPerAccount) {            nbReq = maxReservedPerAccount;        }                // Anything beyond the minimum comes from extra items if there's        // enough.        if (nbReq > minReservedPerAccount) {            extra = holdExtraKeepSome(nbReq - minReservedPerAccount);            nbReq = minReservedPerAccount;        }                // Then the minimum comes from reserved items, if we can.        reserved = holdReserved(nbReq);        nbReq -= reserved;                // If there's some letf to be had, it means that we're getting        // short on reserved items, we'll try to compensate by getting        // more items from extra, but the app should start getting rid        // of stale accounts if it can.        if (nbReq > 0) {            if (Logging.SHOW_INFO && LOG.isLoggable(Level.INFO)) {                LOG.info("Accepting extra account on a best effort basis.");            }                        extra += holdExtraKeepSome(nbReq);            if (extra + reserved < minReservedPerAccount) {                // Even that was not enough to reach our minimal commitment.                // The app should realy consider some cleanup.                if (Logging.SHOW_WARNING && LOG.isLoggable(Level.WARNING)) {                    LOG.warning("[" + myName + "] Accepting extra account with below-minimal commitment:[" + userObject + "]");                }            }        }                if ((maxExtra > maxExtraPerAccount) || (maxExtra < 0)) {            maxExtra = maxExtraPerAccount;        }                return new ClientAccount(reserved, extra, maxExtra, userObject);    }}

⌨️ 快捷键说明

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