Oracle8i Java Developer's Guide Release 3 (8.1.7) Part Number A83728-01 |
Library | Service | Contents | Index

## Threading in JServer

The Aurora JVM implements a non-preemptive threading model. With this model, the JVM runs all Java threads on a single operating system thread. It schedules them in a round-robin fashion and switches between them only when they block. Blocking occurs when you, for example, invoke the `Thread.yield()` method or wait on a network socket by invoking `mySocket.read()`.

Advantages of JServer's Threading Model | Disadvantages
--- | ---
simple to program efficient to implement in the Java virtual machine, because a thread switch does not require any system calls safer, because the JVM can detect a deadlock that would hang a preemptive JVM and can then raise a runtime exception | does not exhibit any concurrency lack of portability performance considerations, because of the system calls required for locking when blocking the thread memory scalability, because efficient multi-threaded memory allocation requires a larger pool of memory

Oracle chose this model because any Java application written on a single-processor system works identical to one written on a multi-processor system. Also, the lack of concurrency among Java threads is not an issue because Aurora is embedded in the database, which provides a higher degree of concurrency than any conventional JVM.

There is no need to use threads within the application logic because the Oracle server preemptively schedules the session JVMs. If you must support hundreds or thousands of simultaneous transactions, start each one in its own JVM. This is exactly what happens when you create a session on the JServer. The normal transactional capabilities of the Oracle database server accomplish coordination and data transfer between the Java virtual machines. This is not a scalability issue, because in contrast to the 6 to 8 MB memory footprint of the typical Java virtual machine, the Oracle server can create thousands of Java virtual machines, with each one taking less than 40 KB.

Threading is managed within Aurora by servicing a single thread until it completes or blocks. If the thread blocks, by yielding or waiting on a network socket, the JVM will service another thread. However, if the thread never blocks, it is serviced until completed.

The Aurora JVM has added the following features for better performance and thread management:

- System calls are at a minimum. Aurora has exchanged some of the normal system calls with non-system solutions. For example, entering a monitor-synchronized block or method does not require a system call.

- Deadlocks are detected.

  - Aurora monitors for deadlocks between threads. If a deadlock occurs, Aurora terminates one of the threads and throws the `oracle.aurora.vm.DeadlockError` exception.

  - Single-threaded applications cannot suspend. If the application has only a single thread and you try to suspend it, the `oracle.aurora.vm.LimboError` exception is thrown.

#### Thread Lifecycle

In the single-threaded execution case, the call ends when one of the following events occurs:

1. The thread returns to its caller.

2. An exception is thrown and is not caught in Java code.

3. The `System.exit()`, `oracle.aurora.vm.OracleRuntime.exitCall()`, or `oracle.aurora.mts.session.Session.THIS_SESSION().endSession()` method is invoked.

If the initial thread creates and starts other Java threads, the rules about when a call ends are slightly more complicated. In this case, the call ends in one of the following two ways:

1. The main thread returns to its caller, or an exception is thrown and not caught in this thread, and all other non-daemon threads complete execution. Non-daemon threads complete either by returning from their initial method or because an exception is thrown and not caught in the thread.

2. Any thread invokes the `System.exit()`, `oracle.aurora.vm.OracleRuntime.exitCall()`, or `oracle.aurora.mts.session.Session.THIS_SESSION().endSession()` method.

When a call ends because of a return and/or uncaught exceptions, Aurora throws a `ThreadDeathException` in all daemon threads. The `ThreadDeathException` essentially forces threads to stop execution.

When a call ends because of a call to `System.exit()`, `oracle.aurora.vm.OracleRuntime.exitCall()`, or `oracle.aurora.vm.oracleRuntime.exitSession()`, Aurora ends the call abruptly and terminates all threads, but does not throw `ThreadDeathException`.

During the execution of a single call, a Java program can recursively cause more Java code to be executed. For example, your program can issue a SQL query using JDBC or SQLJ that in turn causes a trigger written in Java to be invoked. All the preceding remarks regarding call lifetime apply to the top-most call to Java code, not to the recursive call. For example, a call to `System.exit()` from within a recursive call will exit the entire top-most call to Java, not just the recursive call.

| Copyright © 1996-2000, Oracle Corporation. All Rights Reserved. |
Library | Service | Contents | Index