Selathco 0.91 generated HTML
Predchozi Table of contents ) Dalsi

3. Queue Facilities

Although the Java language provides a broad spectrum of classes intended to be directly used as queues, J-Sim introduces two new ones, based on the philosophy of the Simula language and used by C-Sim, too. The new classes are named JSimHead and JSimLink.

In Simula, three classes exist: LINKAGE, HEAD and LINK. HEAD represents the head of a queue where various objects can be inserted. LINK represents an object holding user's information, supposed to be inserted into a queue. Both these classes are derived from LINKAGE which is a class having the ability to be linked, i.e. to be inserted into a queue. Since the HEAD class is derived from LINKAGE, it has this ability too; therefore, the user can construct queues having other queues as their elements. The user must derive a new class from LINK and put his information into it because instances of LINK are not supposed to hold any information. Therefore, the LINK class can never be used in a real application, but thanks to inheritance and polymorphism all parameters of operations can be typed as LINK.

In J-Sim, this principle was considerably simplified but it still has all Simula's possibilities. Although the LINKAGE class was not implemented at all, J-Sim's queues have ability to contain objects of any Java class. This is due to the fact that JSimLink does not keep user's information inside but has just a reference to the information. This reference is typed as Object which is superclass of all possible classes. Since JSimHead is a subclass of Object, as all classes, the user can create queues containing other queues. There is therefore no need to create subclasses of JSimLink, although it is possible (but much more complicated for the user).

A simple model of a queue (instance of JSimHead) containing four elements (instances of JSimLink) is depicted in figure 3. on page 3. Note that the elements of the queue do not necessarily hold information of the same type, i.e. instances of the same class.

A Simple Queue Having Four Elements
A Simple Queue Having Four Elements

Inside the queue, elements are organized in a double-ended bi-directional list and the queue holds information about both ends of the list (head and tail). Every element holds information about the queue it is inserted in, about its data and about the next and previous element in the list. An element can be inserted into one queue only; however, later it can be removed from the queue and inserted into another one.

Since the information held by an element is always an instance of a class, it is not possible to insert there variables of primitive data types like int, float, double, etc. Fortunately, it does not cause any problems since the Java language provides a class (1) for each of these primitive data types, being able to hold information about one variable of its respective type. The Integer class corresponds to the int type, Float to float, Double to double, etc.

The following subchapters will discuss internals of the two classes as well as the way how they cooperate.

3.1. Queues - The JSimHead Class

The JSimHead class can be considered as a container where data of various types are stored in a defined way. It provides some useful functions inherited from Simula's queue concept as well as some new ones added in J-Sim. Maybe it is surprising that it does not offer any possibility how to insert an element into the queue or how to remove it from the queue. In J-Sim, these services are provided by the elements themselves, not by the queue. They will be discussed in chapter 3.2.1..

3.1.1. Simula-like Functions

Only five basic methods, taken from Simula, are offered by the JSimHead class: The empty() method returns a logical value saying whether the queue is empty or not. The queue is empty if it contains no elements. The method's header:


public boolean empty()

The cardinal() method returns the number of elements currently present in the queue. The method's header:

public long cardinal()

The first() method returns the element which is at the beginning of the queue. If the queue is empty, null is returned. Note that it returns a reference to JSimLink; therefore, it is necessary to use other functions, described in chapter 3.2.2., to get the real data. The method's header:

public JSimLink first()

The last() method returns the element which is at the end of the queue. If the queue is empty, null is returned. Like in the previous case, it returns a reference to JSimLink; therefore, it is necessary to use other functions, described in chapter 3.2.2., to get the real data. The method's header:

public JSimLink first()

The clear() method removes all elements from the queue and sets queue statistics to their initial values. While removing the elements from the queue, they may be disposed. Whether they will be disposed or not depends on the number of links pointing to them. If there is at least one such link (except of this queue's links), the element will be preserved. Otherwise, it will be destroyed automatically by JVM. The method's header:

public void clear()

3.1.2. Other Useful Functions

Since J-Sim adds new ideas to Simula's queue concept, it provides some new methods making queues easier to use and more comprehensible. The new methods are as follows:

The getFirstData() method returns a reference to the data that the first element in the queue points to. If the queue is empty, null is returned. Note that the user must always retype the result to the required class in order to have access to all fields and methods of the class. The method's header:


public Object getFirstData()

The getFirstDataType() method returns the name of the class that the first element's data object is instance of. The name returned is fully qualified, e.g. "java.lang.Integer". If the queue is empty, null is returned. The method's header:

public String getFirstDataType()

The getLastData() method returns a reference to the data that the last element in the queue points to. If the queue is empty, null is returned. Like in the previous case, the user must always retype the result to the required class in order to have access to all fields and methods of the class. The method's header:

public Object getLastData()

The getLastDataType() method returns the name of the class that the last element's data object is instance of. The name returned is fully qualified, e.g. "java.lang.Integer". If the queue is empty, null is returned. The method's header:

public String getLastDataType()

The getCurrentTime() method returns the current time of the simulation that the queue belongs to. This method is especially useful for statistics purposes. The method's header:

public double getCurrentTime()

3.1.3. Statistics Functions

Since the queueing theory introduces some queues' quantities that can be measured or theoretically computed, J-Sim provides functions for their computation, too. They are as follows:

The getLw() method returns the average length LW of the queue. The length is computed over a time interval whose left limit is the time of queue's creation (or the time when last clear() was invoked) and the right limit is the current time. This quantity's sign is LW. The method's header:


public double getLw()

The getTw() method returns the average waiting time TW that the elements ever inserted into the queue have spent there. When clear() is called, this number is set to zero. This quantity's sign is TW. The method's header:

public double getTw()

3.1.4. Managing Data

When an element wants to insert itself into a queue or to remove itself from a queue, it must cooperate with the queue the operation concerns. When such an operation is performed, the queue's statistics must be updated and sometimes, the head or the tail of the queue must be adjusted. The following methods are called exclusively from JSimLink and therefore can be marked as protected:

The setHead() method simply replaces the value of head by the value passed as parameter to the method. No other action is performed. The method's header:


protected final void setHead(JSimLink newHead)

The setTail() method simply replaces the value of the tail by the value passed as parameter to the method. No other action is performed. The method's header:

protected final void setTail(JSimLink newTail)

The putAtHead() method puts a new element at the head of the queue, doing some necessary actions in order to keep the queue in consistent state. The method's header:

protected final void putAtHead(JSimLink newHead)

The putAtTail() method puts a new element at the tail of the queue, doing some necessary actions in order to keep the queue in consistent state. The method's header:

protected final void putAtTail(JSimLink newTail)

The incNoOfItems() method increments an internal counter of elements present in the queue and updates sumLw which serves as intermediate result for computation of LW. The method's header:

protected final void incNoOfItems()

The decNoOfItems() method decrements an internal counter of elements present in the queue and updates sumLw and sumTw which serve as intermediate results for computation of LW and TW. The method must know when the element being removed entered the queue in order to update sumTw correctly. This time is passed to the method as a parameter. The method's header:

protected final void decNoOfItems(double whenEntered)

3.2. Elements - The JSimLink Class

Instances of JSimLink are elementary units of information having the ability to be inserted into a queue (instance of JSimHead). Since they can hold any type of information, they are supposed to be used directly, thus there is no need to create their subclasses. This is a fundamental difference from C-Sim and Simula, where this was the only way how to insert data into a queue. Thanks to polymorphism, this possibility is still kept in J-Sim and will be discussed in chapter 3.2.3..

3.2.1. Simula-like Functions

The following methods, taken from Simula, take care about inserting an element into a queue or removing it from the queue in which the element is already inserted. All methods are supposed to be called in this way: element.method(x).

The into() method inserts the element into a queue specified as parameter. The element is always inserted at the end of the queue. If the element is already inserted in a queue, an exception is thrown out. The method's header:


public final void into(JSimHead queue)
     throws JSimSecurityException

The follow() method inserts the element into the same queue that the parameter of the method is inserted in, and right after the parameter. Therefore, the parameter of the method will become element's "left neighbour". If the element is already inserted in a queue, an exception is thrown out. The method's header:

public final void follow(JSimLink otherItem)
     throws JSimSecurityException

The precede() method inserts the element into the same queue that the parameter of the method is inserted in, and right before the parameter. Therefore, the parameter of the method will become element's "right neighbour". If the element is already inserted in a queue, an exception is thrown out. The method's header:

public final void precede(JSimLink otherItem)
     throws JSimSecurityException

The out() method removes the element from the queue it has been inserted in. If the element is not inserted in any queue, nothing happens. The method's header:

public final void out()

3.2.2. Other Useful Functions

Other functions, available in the JSimLink class, serve mainly to provide access to the data that the element only points to but does not contain directly.

The getEnterTime() method returns the time when the element was inserted into a queue. If it has not been inserted into any queue yet, it returns zero. The method's header:


public final double getEnterTime()

The getDataType() method returns the fully qualified name of the class that the data object pointed to by this element is instance of. The fully qualified name contains the name of the package the class belongs to, e.g. "java.lang.Number". The method's header:

public String getDataType()

The getData() method returns a reference to the data object. The reference is typed as Object so the user will always need to retype it to his desired type. The actual type can be obtained by calling the getDataType() method. The method's header:

public Object getData()

3.2.3. Direct Use versus Inheritance

Although J-Sim provides a very intuitive way how to insert data of any type (instances of any class) into a queue without inheriting new classes from JSimLink, some users may prefer the way they used in Simula or C-Sim.

Some advantages of the imlicitly used way should be mentioned:

  • No new classes have to be created.

  • Any data can be inserted in a queue, even data of different types in the same queue.

  • The data type of every queue element can be determined dynamically and according to that, the data obtained from the queue can be retyped dynamically in the right way.

If the user, despite these advantages, tries to inherit his own subclasses of JSimLink and put his data directly to them, he should be aware of the following necessary steps that must be performed:

  1. A new constructor must be created since JSimLink does not have an implicit one.

  2. The getDataType() method must be overwritten since the old one will probably return null because the data object will be initialized to null or not initialized at all.

  3. The getData() method must be overwritten because of the same reasons. It should return a reference to an object fully owned by the new subclass.

  4. No other methods can be overwritten since they are all marked as final. However, new ones can be added.


  • (1) These classes are called "wrapper classes".

Predchozi
Converted by Selathco 0.91 on 01.09.2001 18:44
Dalsi