schedulerservice.java

来自「jxme的一些相关程序,主要是手机上程序开发以及手机和计算机通信的一些程序资料,」· Java 代码 · 共 371 行

JAVA
371
字号
/*
 *  Copyright (c) 2001 Sun Microsystems, Inc. All rights
 *  reserved.
 *
 *  Redistribution and use in source and binary forms, with or without
 *  modification, are permitted provided that the following conditions
 *  are met:
 *
 *  1. Redistributions of source code must retain the above copyright
 *  notice, this list of conditions and the following disclaimer.
 *
 *  2. Redistributions in binary form must reproduce the above copyright
 *  notice, this list of conditions and the following disclaimer in
 *  the documentation and/or other materials provided with the
 *  distribution.
 *
 *  3. The end-user documentation included with the redistribution,
 *  if any, must include the following acknowledgment:
 *  "This product includes software developed by the
 *  Sun Microsystems, Inc. for Project JXTA."
 *  Alternately, this acknowledgment may appear in the software itself,
 *  if and wherever such third-party acknowledgments normally appear.
 *
 *  4. The names "Sun", "Sun Microsystems, Inc.", "JXTA" and "Project JXTA"
 *  must not be used to endorse or promote products derived from this
 *  software without prior written permission. For written
 *  permission, please contact Project JXTA at http://www.jxta.org.
 *
 *  5. Products derived from this software may not be called "JXTA",
 *  nor may "JXTA" appear in their name, without prior written
 *  permission of Sun.
 *
 *  THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
 *  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 *  OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 *  DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
 *  ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
 *  USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 *  ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 *  OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
 *  OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 *  SUCH DAMAGE.
 *
 *  ====================================================================
 *
 *  This software consists of voluntary contributions made by many
 *  individuals on behalf of Project JXTA. For more
 *  information on Project JXTA, please see
 *  <http://www.jxta.org/>.
 *
 *  This license is based on the BSD license adopted by the Apache Foundation.
 *
 *  $Id: SchedulerService.java,v 1.2 2002/03/04 21:38:14 echtcherbina Exp $
 */
package net.jxta.impl.cm;

/**
 *  Description of the Class
 *
 * THIS CLASS MUST NOT CALL ANYTHING OUTSIDE ITSELF WHILE SYNCHRONIZED.
 * To avoid dealocks we maintain strick layering of sycnh. This is in layer 0.
 * The indexer is in layer 0 too.
 * The file expiration service is layer 1.
 * The cm is layer 2.
 */
public class SchedulerService implements Runnable {

        volatile boolean done;
        SchedulerPriorityQueue heap;

        /**
         *  Constructor for the SchedulerService object
         */
        public SchedulerService() {

                this.done = false;
                this.heap = new SchedulerPriorityQueue( 1024, 2 );
        }


        /**
         *  Description of the Method
         *
         *@param  action   Description of Parameter
         *@param  timeout  Description of Parameter
         *@return          Description of the Returned Value
         */
        public synchronized PendingAction scheduleAction( Action action,
                                                          long timeout ) {
                PendingAction el = null;

                if ( timeout >= 0 ) {
                        // throw IllegalArgumentException ("Timeout value " +
                        // "cannot be negative.");

                        el = new PendingAction( action,
                                        System.currentTimeMillis() + timeout );
                        heap.put( el );
                        if ( heap.top() == el ) {
                                notify();
                        }
                }
                return el;
        }


        /**
         * Description of the Method
         *
         * cancel does not call anything outside and is not synchronized.
         * all synchro is provided here. PendingAction.cancel is *not* a
         * public method.
         *
         * @param  pendingAction  Description of Parameter
         */
        private synchronized void doCancel( PendingAction pendingAction ) {

            // Try and cancel if it is not too late.
            pendingAction.cancel();

            // Cancel may not do anything if it was no-longer cancellable
            // because it has been poped from the queue already and is about
            // to be performed (which happens out of synchronized).
            // In that case, head.top() cannot be equal to pending action
            // and thus we can execute the following without checking any
            // further.
            if ( heap.top() == pendingAction ) {
                notify();
            }
        }

        /**
         * Description of the Method
         *
         * The part that affects the queue is done in doCancel.
         * The main task of this routine is to make sure that perform
         * may never happen or finish after cancelAction returns.
         *
         * @param  pendingAction  Description of Parameter
         */
        public void cancelAction( PendingAction pendingAction ) {

            // Do the part of cancel that affects the queue.
            doCancel(pendingAction);

            // Make sure that if perform beat us to the finish line
            // then it is actually finished.
            pendingAction.noPerform();
        }

        /**
         * Main processing method for the SchedulerService object
         */
        public void run() {
                Thread.currentThread().setPriority(Thread.MIN_PRIORITY);
                while ( !done ) {
		    
                    PendingAction e = getNextEvent();
                    if ( done ) break;

                    try {
                        e.perform( this );
                    } catch ( Exception ex ) {
                        ex.printStackTrace();
                    }

		    Thread.yield();
                }
        }

        /**
         *  Gets the nextEvent attribute of the SchedulerService object
         *
         *@return    The nextEvent value
         */
        private synchronized PendingAction getNextEvent() {
                PendingAction el;
                long timeout;
                // Currently no-one sets done from the outside, but that could
                // change.
                if ( done ) {
                        return null;
                } else if ( ( el = (PendingAction) heap.top() ) == null ) {
                        timeout = Long.MAX_VALUE;
                } else {
                        timeout = el.time - System.currentTimeMillis();
                }
                try {
                        while ( !done ) {
                                if ( timeout > 0 ) {
                                        wait( timeout );
                                }
                                if ( done ) {
                                        // we were stopped

                                        break;
                                } else if ( el != heap.top() ) {
                                        // new minimum element inserted
                                        el = (PendingAction) heap.top();
                                        timeout = el.time - System.currentTimeMillis();

                                } else {
                                        // we were woken up to act

                                        heap.pop();
                                        el.nonCancelable();
                                        return el;
                                }
                        }
                } catch ( InterruptedException e ) {
                        done = true;
                }
                return null;
        }


        /**
         *  Description of the Class
         */
        public class PendingAction {

                SchedulerService.Action action;
                boolean cancelable = true;
                long time;

                /**
                 *  Constructor for the PendingAction object
                 *
                 *@param  action  Description of Parameter
                 *@param  time    Description of Parameter
                 */
                PendingAction( SchedulerService.Action action, long time ) {

                        this.action = action;
                        this.time = time;
                }

                /**
                 *  Gets the time attribute of the PendingAction object
                 *
                 *@return    The time value
                 */
                public long getTime() {
                        return time;
                }

                /**
                 *  Description of the Method
                 *
                 *@param  ss  Description of Parameter
                 */
                void perform( SchedulerService ss ) {

                    // Although this method is invoked out of synchronized
                    // we can trust the stability of action because it cannot
                    // be cleared after this PendingAction has been poped off
                    // the queue. PendingActions are poped off the queue
                    // and made uncancelable under synchronized, and then
                    // perform() is invoked out of synchronized.

                    if ( action != null ) {
                        try {

                            action.perform( ss );

                        } finally {  // Make sure we do this.

                            // The following is to permit cancellers to wait
                            // for perform to done. So that it is garanteed
                            // that performing the action can in no-way extend
                            // past the return from cancel, even if cancel was
                            // too late.
                            synchronized(this) {
                                action = null;
                                notifyAll();
                            }
                        }
                    }
                }

                /**
                 * Prevent cancellation
                 * This is invoked under synchronized after poping this
                 * PendingAction off the Queue and before calling perform.
                 */
                void nonCancelable() {
                    cancelable = false;
                }

                /**
                 *  Cancel if we still can
                 */
                void cancel() {
                    // We must check if this action is cancelable first.
                    // If this action has already been poped off the queue
                    // then it may be in the process or about to be "performed"
                    // (which happens out of synchronized). In that case we
                    // must not clear cancel lest we create an NPE.
                    if (cancelable) {
                        action = null;
                    }
                }

                /**
                 * makes sure that any perform that might have been going on
                 * while we were trying to cancel either did not occur (cancel
                 * worked and set action to null) or is finished (and
                 * perform set action to null)
                 */
                synchronized void noPerform() {
                    try {
                        while (action != null) {
                            wait();
                        }
                    } catch (InterruptedException intr) {
                        // Just return then.
                    }
                }
        }


        /**
         *  Description of the Class
         */
        class SchedulerPriorityQueue extends PriorityQueue {

                /**
                 *  Constructor for the SchedulerPriorityQueue object
                 *
                 *@param  heapSize  Description of Parameter
                 *@param  increase  Description of Parameter
                 */
                SchedulerPriorityQueue( int heapSize, int increase ) {
                        super.initialize( heapSize, increase );
                }

                /**
                 *  Description of the Method
                 *
                 *@param  o1  Description of Parameter
                 *@param  o2  Description of Parameter
                 *@return     Description of the Returned Value
                 */
                protected boolean lessThan( Object o1, Object o2 ) {
                        PendingAction a1 = (PendingAction) o1;
                        PendingAction a2 = (PendingAction) o2;

                        return a1.time < a2.time;
                }
        }

        /**
         *  Description of the Class
         */
        public static interface Action {

                /**
                 *  Description of the Method
                 *
                 *@param  ss  Description of Parameter
                 */
                void perform( SchedulerService ss );
                // called when alarm expires
        }
}



⌨️ 快捷键说明

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