appcontext.java

来自「This is a resource based on j2me embedde」· Java 代码 · 共 761 行 · 第 1/2 页

JAVA
761
字号
        *         frames[i].dispose(); // Dispose of all top-level Frames        *     }        *     synchronized(notificationLock) {        *         notificationLock.notifyAll(); // Notify caller that we're done        *     }        * } };        * synchronized(notificationLock) {        *     SunToolkit.postEvent(this,        *         new InvocationEvent(Toolkit.getDefaultToolkit(), runnable));        *     try {        *         notificationLock.wait(DISPOSAL_TIMEOUT);        *     } catch (InterruptedException e) { }        *  }        */        // Next, we post another InvocationEvent to the end of the        // EventQueue.  When it's executed, we know we've executed all        // events in the queue.        Runnable runnable = new Runnable() { public void run() {            synchronized(notificationLock) {                notificationLock.notifyAll(); // Notify caller that we're done            }        } };        synchronized(notificationLock) {            SunToolkit.postEvent(this,                new InvocationEvent(Toolkit.getDefaultToolkit(), runnable));            try {                notificationLock.wait(DISPOSAL_TIMEOUT);            } catch (InterruptedException e) { }        }        // Next, we interrupt all Threads in the ThreadGroup        this.threadGroup.interrupt();            // Note, the EventDispatchThread we've interrupted may dump an            // InterruptedException to the console here.  This needs to be            // fixed in the EventDispatchThread, not here.        // Next, we sleep 10ms at a time, waiting for all of the active        // Threads in the ThreadGroup to exit.        long startTime = System.currentTimeMillis();        long endTime = startTime + (long)THREAD_INTERRUPT_TIMEOUT;        while ((this.threadGroup.activeCount() > 0) &&               (System.currentTimeMillis() < endTime)) {            try {                Thread.sleep(10);            } catch (InterruptedException e) { }        }        // Then, we stop any remaining Threads        // this.threadGroup.stop();        // Next, we sleep 10ms at a time, waiting for all of the active        // Threads in the ThreadGroup to die.        startTime = System.currentTimeMillis();        endTime = startTime + (long)THREAD_INTERRUPT_TIMEOUT;        while ((this.threadGroup.activeCount() > 0) &&               (System.currentTimeMillis() < endTime)) {            try {                Thread.sleep(10);            } catch (InterruptedException e) { }        }        // Next, we remove this and all subThreadGroups from threadGroup2appContext        int numSubGroups = this.threadGroup.activeGroupCount();        if (numSubGroups > 0) {            ThreadGroup [] subGroups = new ThreadGroup[numSubGroups];            numSubGroups = this.threadGroup.enumerate(subGroups);            for (int subGroup = 0; subGroup < numSubGroups; subGroup++) {                threadGroup2appContext.remove(subGroups[subGroup]);            }        }	threadGroup2appContext.remove(this.threadGroup);        MostRecentThreadAppContext recent = mostRecentThreadAppContext;        if ((recent != null) && (recent.appContext == this))            mostRecentThreadAppContext = null;                // If the "most recent" points to this, clear it for GC        // Finally, we destroy the ThreadGroup entirely.        try {            this.threadGroup.destroy();        } catch (IllegalThreadStateException e) {            // Fired if not all the Threads died, ignore it and proceed        }        synchronized (table) {            this.table.clear(); // Clear out the Hashtable to ease garbage collection        }        numAppContexts--;        mostRecentKeyValue = null;    }/*   There is no AWTAutoShutdown in pbp right now**    static final class PostShutdownEventRunnable implements Runnable {*        private final AppContext appContext;**        public PostShutdownEventRunnable(AppContext ac) {*            appContext = ac;*        }*        *        public void run() {*            final EventQueue eq = (EventQueue)appContext.get(EVENT_QUEUE_KEY);*            if (eq != null) {*                eq.postEvent(AWTAutoShutdown.getShutdownEvent());*            }*        }*    }***    static final class CreateThreadAction implements PrivilegedAction {*        private final AppContext appContext;*        private final Runnable runnable;**        public CreateThreadAction(AppContext ac, Runnable r) {*            appContext = ac;*            runnable = r;*        }*        *        public Object run() {*            Thread t = new Thread(appContext.getThreadGroup(), runnable);*            t.setContextClassLoader(appContext.getContextClassLoader());*            t.setPriority(Thread.NORM_PRIORITY + 1);*            t.setDaemon(true);*            return t;*        }*    }***    static void stopEventDispatchThreads() {**        // Use clone, so that concurrent modification of threadGroup2appContext **        // won't mess up the enumeration.**        Hashtable clone = (Hashtable)threadGroup2appContext.clone();*        Enumeration allAppContexts = clone.elements();**        while (allAppContexts.hasMoreElements()) {*            AppContext appContext = (AppContext)allAppContexts.nextElement();**            Runnable r = new PostShutdownEventRunnable(appContext);*            // For security reasons EventQueue.postEvent should only be called*            // on a thread that belongs to the corresponding thread group.*            if (appContext != AppContext.getAppContext()) {*                // Create a thread that belongs to the thread group associated*                // with the AppContext and invokes EventQueue.postEvent.*                PrivilegedAction action = new CreateThreadAction(appContext, r);*                Thread thread = (Thread)AccessController.doPrivileged(action);*                thread.start();*            } else {*                r.run();*            }*        }*    }*/    private MostRecentKeyValue mostRecentKeyValue = null;    /**     * Returns the value to which the specified key is mapped in this context.     *     * @param   key   a key in the AppContext.     * @return  the value to which the key is mapped in this AppContext;     *          <code>null</code> if the key is not mapped to any value.     * @see     #put(Object, Object)     * @since   JDK1.2     */    public Object get(Object key) {        // Note: this most recent key/value caching is thread-hot.        // A simple test using SwingSet found that 72% of lookups        // were matched using the most recent key/value.  By instantiating        // a simple MostRecentKeyValue object on cache misses, the        // cache hits can be processed without synchronization.        MostRecentKeyValue recent = mostRecentKeyValue;        if ((recent != null) && (recent.key == key)) {            return recent.value;        }        /*         * The most recent reference should be updated inside a synchronized         * block to avoid a race when put() and get() are executed in         * parallel on different threads.         */        synchronized (table) {            Object value = table.get(key);            mostRecentKeyValue = new MostRecentKeyValue(key, value);            return value;        }    }    /**     * Maps the specified <code>key</code> to the specified      * <code>value</code> in this AppContext.  Neither the key nor the      * value can be <code>null</code>.     * <p>     * The value can be retrieved by calling the <code>get</code> method      * with a key that is equal to the original key.      *     * @param      key     the AppContext key.     * @param      value   the value.     * @return     the previous value of the specified key in this      *             AppContext, or <code>null</code> if it did not have one.     * @exception  NullPointerException  if the key or value is     *               <code>null</code>.     * @see     #get(Object)     * @since   JDK1.2     */    public Object put(Object key, Object value) {        synchronized (table) {            MostRecentKeyValue recent = mostRecentKeyValue;            if ((recent != null) && (recent.key == key))                recent.value = value;            return table.put(key, value);        }    }    /**     * Removes the key (and its corresponding value) from this      * AppContext. This method does nothing if the key is not in the     * AppContext.     *     * @param   key   the key that needs to be removed.     * @return  the value to which the key had been mapped in this AppContext,     *          or <code>null</code> if the key did not have a mapping.     * @since   JDK1.2     */    public Object remove(Object key) {        synchronized (table) {            MostRecentKeyValue recent = mostRecentKeyValue;            if ((recent != null) && (recent.key == key))                recent.value = null;            return table.remove(key);        }    }    /**     * Returns the root ThreadGroup for all Threads contained within     * this AppContext.     * @since   JDK1.2     */    public ThreadGroup getThreadGroup() {        return threadGroup;    }    /**     * Returns the context ClassLoader that was used to create this     * AppContext.     *     * @see java.lang.Thread#getContextClassLoader     */    public ClassLoader getContextClassLoader() {        return contextClassLoader;    }    /**     * Returns a string representation of this AppContext.     * @since   JDK1.2     */    public String toString() {        return getClass().getName() + "[threadGroup=" + threadGroup.getName() + "]";    }    /**     * Returns an array of all the property change listeners     * registered on this component.     *     * @return all of this component's <code>PropertyChangeListener</code>s     *         or an empty array if no property change     *         listeners are currently registered     *     * @see      #addPropertyChangeListener     * @see      #removePropertyChangeListener     * @see      #getPropertyChangeListeners(java.lang.String)     * @see      java.beans.PropertyChangeSupport#getPropertyChangeListeners     * @since    1.4    * public synchronized PropertyChangeListener[] getPropertyChangeListeners() {    *     if (changeSupport == null) {    *         return new PropertyChangeListener[0];    *     }    *     return changeSupport.getPropertyChangeListeners();    * }     */      /**     * Adds a PropertyChangeListener to the listener list for a specific     * property. The specified property may be one of the following:     * <ul>     *    <li>if this AppContext is disposed ("disposed")</li>     * </ul>     * <p>     * If listener is null, no exception is thrown and no action is performed.     *     * @param propertyName one of the property names listed above     * @param listener the PropertyChangeListener to be added     *     * @see #removePropertyChangeListener(java.lang.String, java.beans.PropertyChangeListener)     * @see #getPropertyChangeListeners(java.lang.String)     * @see #addPropertyChangeListener(java.lang.String, java.beans.PropertyChangeListener)    * public synchronized void addPropertyChangeListener(    *                          String propertyName,    *                          PropertyChangeListener listener) {*	if (listener == null) {*	    return;*	}*	if (changeSupport == null) {*	    changeSupport = new PropertyChangeSupport(this);*	}*	changeSupport.addPropertyChangeListener(propertyName, listener);    *}     */    /**     * Removes a PropertyChangeListener from the listener list for a specific     * property. This method should be used to remove PropertyChangeListeners     * that were registered for a specific bound property.     * <p>     * If listener is null, no exception is thrown and no action is performed.     *     * @param propertyName a valid property name     * @param listener the PropertyChangeListener to be removed     *     * @see #addPropertyChangeListener(java.lang.String, java.beans.PropertyChangeListener)     * @see #getPropertyChangeListeners(java.lang.String)     * @see #removePropertyChangeListener(java.beans.PropertyChangeListener)    *public synchronized void removePropertyChangeListener(    *                         String propertyName,    *                         PropertyChangeListener listener) {    *    if (listener == null || changeSupport == null) {    *        return;    *    }    *    changeSupport.removePropertyChangeListener(propertyName, listener);    *}     */    /**     * Returns an array of all the listeners which have been associated      * with the named property.     *     * @return all of the <code>PropertyChangeListeners</code> associated with     *         the named property or an empty array if no listeners have      *         been added     *     * @see #addPropertyChangeListener(java.lang.String, java.beans.PropertyChangeListener)     * @see #removePropertyChangeListener(java.lang.String, java.beans.PropertyChangeListener)     * @see #getPropertyChangeListeners     * @since 1.4    *public synchronized PropertyChangeListener[] getPropertyChangeListeners(     *                                                   String propertyName) {    *    if (changeSupport == null) {    *        return new PropertyChangeListener[0];    *    }    *    return changeSupport.getPropertyChangeListeners(propertyName);    *}     */}final class MostRecentThreadAppContext {    final Thread thread;    final AppContext appContext;    MostRecentThreadAppContext(Thread key, AppContext value) {        thread = key;        appContext = value;    }}final class MostRecentKeyValue {    final Object key;    Object value;    MostRecentKeyValue(Object k, Object v) {        key = k;        value = v;    }}

⌨️ 快捷键说明

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