coroutinemanager.java

来自「java jdk 1.4的源码」· Java 代码 · 共 382 行 · 第 1/2 页

JAVA
382
字号
/* * The Apache Software License, Version 1.1 * * * Copyright (c) 1999 The Apache Software Foundation.  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 *        Apache Software Foundation (http://www.apache.org/)." *    Alternately, this acknowledgment may appear in the software itself, *    if and wherever such third-party acknowledgments normally appear. * * 4. The names "Xalan" and "Apache Software Foundation" must *    not be used to endorse or promote products derived from this *    software without prior written permission. For written  *    permission, please contact apache@apache.org. * * 5. Products derived from this software may not be called "Apache", *    nor may "Apache" appear in their name, without prior written *    permission of the Apache Software Foundation. * * 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 the Apache Software Foundation and was * originally based on software copyright (c) 1999, Lotus * Development Corporation., http://www.lotus.com.  For more * information on the Apache Software Foundation, please see * <http://www.apache.org/>. */package org.apache.xml.dtm.ref;import java.util.*;import org.apache.xml.dtm.*;import org.apache.xalan.res.XSLTErrorResources;import org.apache.xalan.res.XSLMessages;/** * <meta name="usage" content="internal"/> * <p>Support the coroutine design pattern.</p> *  * <p>A coroutine set is a very simple cooperative non-preemptive * multitasking model, where the switch from one task to another is * performed via an explicit request. Coroutines interact according to * the following rules:</p> * * <ul> * <li>One coroutine in the set has control, which it retains until it * either exits or resumes another coroutine.</li> * <li>A coroutine is activated when it is resumed by some other coroutine * for the first time.</li> * <li>An active coroutine that gives up control by resuming another in * the set retains its context -- including call stack and local variables * -- so that if/when it is resumed, it will proceed from the point at which * it last gave up control.</li> * </ul> * * <p>Coroutines can be thought of as falling somewhere between pipes and * subroutines. Like call/return, there is an explicit flow of control * from one coroutine to another. Like pipes, neither coroutine is * actually "in charge", and neither must exit in order to transfer * control to the other. </p> *  * <p>One classic application of coroutines is in compilers, where both * the parser and the lexer are maintaining complex state * information. The parser resumes the lexer to process incoming * characters into lexical tokens, and the lexer resumes the parser * when it has reached a point at which it has a reliably interpreted * set of tokens available for semantic processing. Structuring this * as call-and-return would require saving and restoring a * considerable amount of state each time. Structuring it as two tasks * connected by a queue may involve higher overhead (in systems which * can optimize the coroutine metaphor), isn't necessarily as clear in * intent, may have trouble handling cases where data flows in both * directions, and may not handle some of the more complex cases where * more than two coroutines are involved.</p> *  * <p>Most coroutine systems also provide a way to pass data between the * source and target of a resume operation; this is sometimes referred * to as "yielding" a value.  Others rely on the fact that, since only * one member of a coroutine set is running at a time and does not * lose control until it chooses to do so, data structures may be * directly shared between them with only minimal precautions.</p> *  * <p>"Note: This should not be taken to mean that producer/consumer * problems should be always be done with coroutines." Queueing is * often a better solution when only two threads of execution are * involved and full two-way handshaking is not required. It's a bit * difficult to find short pedagogical examples that require * coroutines for a clear solution.</p> *  * <p>The fact that only one of a group of coroutines is running at a * time, and the control transfer between them is explicit, simplifies * their possible interactions, and in some implementations permits * them to be implemented more efficiently than general multitasking. * In some situations, coroutines can be compiled out entirely; * in others, they may only require a few instructions more than a * simple function call.</p> * * <p>This version is built on top of standard Java threading, since * that's all we have available right now. It's been encapsulated for * code clarity and possible future optimization.</p> *  * <p>(Two possible approaches: wait-notify based and queue-based. Some * folks think that a one-item queue is a cleaner solution because it's * more abstract -- but since coroutine _is_ an abstraction I'm not really * worried about that; folks should be able to switch this code without * concern.)</p> *  * <p>%TBD% THIS SHOULD BE AN INTERFACE, to facilitate building other * implementations... perhaps including a true coroutine system * someday, rather than controlled threading. Arguably Coroutine * itself should be an interface much like Runnable, but I think that * can be built on top of this.</p> * */public class CoroutineManager{  /** "Is this coroutine ID number already in use" lookup table.   * Currently implemented as a bitset as a compromise between   * compactness and speed of access, but obviously other solutions   * could be applied.   * */  BitSet m_activeIDs=new BitSet();  /** Limit on the coroutine ID numbers accepted. I didn't want the   * in-use table to grow without bound. If we switch to a more efficient   * sparse-array mechanism, it may be possible to raise or eliminate   * this boundary.   */  static final int m_unreasonableId=1024;  /** Internal field used to hold the data being explicitly passed   * from one coroutine to another during a co_resume() operation.   * (Of course implicit data sharing may also occur; one of the reasons   * for using coroutines is that you're guaranteed that none of the   * other coroutines in your set are using shared structures at the time   * you access them.)   *   * %REVIEW% It's been proposed that we be able to pass types of data   * other than Object -- more specific object types, or   * lighter-weight primitives.  This would seem to create a potential   * explosion of "pass x recieve y back" methods (or require   * fracturing resume into two calls, resume-other and   * wait-to-be-resumed), and the weight issue could be managed by   * reusing a mutable buffer object to contain the primitive   * (remember that only one coroutine runs at a time, so once the   * buffer's set it won't be walked on). Typechecking objects is   * interesting from a code-robustness point of view, but it's   * unclear whether it makes sense to encapsulate that in the   * coroutine code or let the callers do it, since it depends on RTTI   * either way. Restricting the parameters to objects implementing a   * specific CoroutineParameter interface does _not_ seem to be a net   * win; applications can do so if they want via front-end code, but   * there seem to be too many use cases involving passing an existing   * object type that you may not have the freedom to alter and may   * not want to spend time wrapping another object around.   * */  Object m_yield=null;  // Expose???  final static int NOBODY=-1;  final static int ANYBODY=-1;

⌨️ 快捷键说明

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