Oracle8i Java Developer's Guide
Release 3 (8.1.7)

Part Number A83728-01





Go to previous page Go to beginning of chapter Go to next page

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

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:

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.

Go to previous page
Go to beginning of chapter
Go to next page
Copyright © 1996-2000, Oracle Corporation.

All Rights Reserved.