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

📄 arraynotificationbuffer.java

📁 java1.6众多例子参考
💻 JAVA
📖 第 1 页 / 共 3 页
字号:
     * listeners to new MBeans, then we query the existing MBeans to     * add listeners to them.  The problem is that a new MBean could     * arrive after we register for creations but before the query has     * completed.  Then we could see the MBean both in the query and     * in an MBean-creation notification, and we would end up     * registering our listener twice.     *     * To solve this problem, we arrange for new MBeans that arrive     * while the query is being done to be added to the Set createdDuringQuery     * and we do not add a listener immediately.  When the query is done,     * we atomically turn off the addition of new names to createdDuringQuery     * and add all the names that were there to the result of the query.     * Since we are dealing with Sets, the result is the same whether or not     * the newly-created MBean was included in the query result.     *     * It is important not to hold any locks during the operation of adding     * listeners to MBeans.  An MBean's addNotificationListener can be     * arbitrary user code, and this could deadlock with any locks we hold     * (see bug 6239400).  The corollary is that we must not do any operations     * in this method or the methods it calls that require locks.     */    private void createListeners() {        logger.debug("createListeners", "starts");        synchronized (this) {            createdDuringQuery = new HashSet<ObjectName>();        }        try {            addNotificationListener(MBeanServerDelegate.DELEGATE_NAME,                                    creationListener, creationFilter, null);            logger.debug("createListeners", "added creationListener");        } catch (Exception e) {            final String msg = "Can't add listener to MBean server delegate: ";            RuntimeException re = new IllegalArgumentException(msg + e);            EnvHelp.initCause(re, e);            logger.fine("createListeners", msg + e);            logger.debug("createListeners", e);            throw re;        }        /* Spec doesn't say whether Set returned by QueryNames can be modified           so we clone it. */        Set<ObjectName> names = queryNames(null, broadcasterQuery);        names = new HashSet<ObjectName>(names);        synchronized (this) {            names.addAll(createdDuringQuery);            createdDuringQuery = null;        }        for (ObjectName name : names)            addBufferListener(name);        logger.debug("createListeners", "ends");    }    private void addBufferListener(ObjectName name) {        checkNoLocks();        if (logger.debugOn())            logger.debug("addBufferListener", name.toString());        try {            addNotificationListener(name, bufferListener, null, name);        } catch (Exception e) {            logger.trace("addBufferListener", e);            /* This can happen if the MBean was unregistered just               after the query.  Or user NotificationBroadcaster might               throw unexpected exception.  */        }    }    private void removeBufferListener(ObjectName name) {        checkNoLocks();        if (logger.debugOn())            logger.debug("removeBufferListener", name.toString());        try {            removeNotificationListener(name, bufferListener);        } catch (Exception e) {            logger.trace("removeBufferListener", e);        }    }    private void addNotificationListener(final ObjectName name,                                         final NotificationListener listener,                                         final NotificationFilter filter,                                         final Object handback)            throws Exception {        try {            AccessController.doPrivileged(new PrivilegedExceptionAction() {                public Object run() throws InstanceNotFoundException {                    mBeanServer.addNotificationListener(name,                                                        listener,                                                        filter,                                                        handback);                    return null;                }            });        } catch (Exception e) {            throw extractException(e);        }    }    private void removeNotificationListener(final ObjectName name,                                            final NotificationListener listener)            throws Exception {        try {            AccessController.doPrivileged(new PrivilegedExceptionAction() {                public Object run() throws Exception {                    mBeanServer.removeNotificationListener(name, listener);                    return null;                }            });        } catch (Exception e) {            throw extractException(e);        }    }    private Set<ObjectName> queryNames(final ObjectName name,                                       final QueryExp query) {        PrivilegedAction<Set<ObjectName>> act =            new PrivilegedAction<Set<ObjectName>>() {                public Set<ObjectName> run() {                    return mBeanServer.queryNames(name, query);                }            };        try {            return AccessController.doPrivileged(act);        } catch (RuntimeException e) {            logger.fine("queryNames", "Failed to query names: " + e);	    logger.debug("queryNames", e);            throw e;        }    }    private static boolean isInstanceOf(final MBeanServer mbs,                                        final ObjectName name,                                        final String className) {        PrivilegedExceptionAction<Boolean> act =            new PrivilegedExceptionAction<Boolean>() {                public Boolean run() throws InstanceNotFoundException {                    return mbs.isInstanceOf(name, className);                }            };        try {            return AccessController.doPrivileged(act);        } catch (Exception e) {            logger.fine("isInstanceOf", "failed: " + e);            logger.debug("isInstanceOf", e);            return false;        }    }    /* This method must not be synchronized.  See the comment on the     * createListeners method.     *     * The notification could arrive after our buffer has been destroyed     * or even during its destruction.  So we always add our listener     * (without synchronization), then we check if the buffer has been     * destroyed and if so remove the listener we just added.     */    private void createdNotification(MBeanServerNotification n) {        final String shouldEqual =            MBeanServerNotification.REGISTRATION_NOTIFICATION;        if (!n.getType().equals(shouldEqual)) {            logger.warning("createNotification", "bad type: " + n.getType());            return;        }        ObjectName name = n.getMBeanName();        if (logger.debugOn())            logger.debug("createdNotification", "for: " + name);        synchronized (this) {            if (createdDuringQuery != null) {                createdDuringQuery.add(name);                return;            }        }        if (isInstanceOf(mBeanServer, name, broadcasterClass)) {            addBufferListener(name);            if (isDisposed())                removeBufferListener(name);        }    }    private class BufferListener implements NotificationListener {	public void handleNotification(Notification notif, Object handback) {	    if (logger.debugOn()) {		logger.debug("BufferListener.handleNotification",		      "notif=" + notif + "; handback=" + handback);	    }	    ObjectName name = (ObjectName) handback;	    addNotification(new NamedNotification(name, notif));	}    }    private final NotificationListener bufferListener = new BufferListener();    private static class BroadcasterQuery            extends QueryEval implements QueryExp {        public boolean apply(final ObjectName name) {            final MBeanServer mbs = QueryEval.getMBeanServer();            return isInstanceOf(mbs, name, broadcasterClass);        }    }    private static final QueryExp broadcasterQuery = new BroadcasterQuery();    private static final NotificationFilter creationFilter;    static {        NotificationFilterSupport nfs = new NotificationFilterSupport();        nfs.enableType(MBeanServerNotification.REGISTRATION_NOTIFICATION);        creationFilter = nfs;    }    private final NotificationListener creationListener =	new NotificationListener() {	    public void handleNotification(Notification notif,					   Object handback) {		logger.debug("creationListener", "handleNotification called");		createdNotification((MBeanServerNotification) notif);	    }	};    private void destroyListeners() {        checkNoLocks();        logger.debug("destroyListeners", "starts");        try {            removeNotificationListener(MBeanServerDelegate.DELEGATE_NAME,                                       creationListener);        } catch (Exception e) {            logger.warning("remove listener from MBeanServer delegate", e);        }        Set<ObjectName> names = queryNames(null, broadcasterQuery);        for (final ObjectName name : names) {            if (logger.debugOn())                logger.debug("destroyListeners",			     "remove listener from " + name);            removeBufferListener(name);        }        logger.debug("destroyListeners", "ends");    }        private void checkNoLocks() {        if (Thread.holdsLock(this) || Thread.holdsLock(globalLock))            logger.warning("checkNoLocks", "lock protocol violation");    }    /**     * Iterate until we extract the real exception     * from a stack of PrivilegedActionExceptions.     */    private static Exception extractException(Exception e) {        while (e instanceof PrivilegedActionException) {            e = ((PrivilegedActionException)e).getException();        }        return e;    }    private static final ClassLogger logger =	new ClassLogger("javax.management.remote.misc",			"ArrayNotificationBuffer");    private final MBeanServer mBeanServer;    private final ArrayQueue<NamedNotification> queue;    private int queueSize;    private long earliestSequenceNumber;    private long nextSequenceNumber;    private Set<ObjectName> createdDuringQuery;    static final String broadcasterClass =        NotificationBroadcaster.class.getName();}

⌨️ 快捷键说明

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