Oracle JVM is based on the database session model, which is a single-client, nonpreemptive threading model. Although Java in Oracle Database allows running threaded programs, it is single-threaded at the execution level. In this model, JVM runs all Java threads associated with a database session on a single operating system thread. Once dispatched, a thread continues execution until it explicitly yields by calling
Thread.yield(), blocks by calling
Socket.read(), or is preempted by the execution engine. Once a thread yields, blocks or is preempted, JVM dispatches another thread.
Starting with 11g release 1 (11.1), Oracle JVM supports thread preemption. Thread preemption is not mandated by the Java specification, but is needed to support the new
java.util.concurrent API, present in JDK1.5, properly.
Oracle JVM has added the following features for better performance and thread management:
System calls are at a minimum. Oracle JVM has exchanged some of the standard system calls with nonsystem solutions. For example, entering a monitor-synchronized block or method does not require a system call.
Deadlocks are detected.
2.12.1 Thread Life Cycle
In a single-threaded application, a call ends when one of the following events occurs:
The thread returns to its caller.
An exception is thrown and is not caught in Java code.
DBMS_JAVA.endsession_and_related_state()method is called.
If the initial thread creates and starts other Java threads, then the call ends in one of the following ways:
The main thread returns to its caller or an exception is thrown and not caught in this thread and in either case all other non-daemon threads are processed. Non-daemon threads complete either by returning from their initial method or because an exception is thrown and not caught in the thread.
Any thread calls the
A call to
Prior to 11g release 1 (11.1), when a call ended because of a call to
oracle.aurora.vm.OracleRuntime.exitCall(), Oracle JVM ended the call abruptly and terminated all threads, in both the dedicated and shared server modes. Since 11g release 1 (11.1), this is addressed by the addition of the following PL/SQL functions to the
FUNCTION endsession RETURN VARCHAR2;
FUNCTION endsession_and_related_state RETURN VARCHAR2;
During a call, a Java program can recursively cause more Java code to be run. For example, your program can issue a SQL query using JDBC or SQLJ that, in turn, calls a trigger written in Java. 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 exits the entire top-most call to Java, not just the recursive call.
2.12.2 System.exit(), OracleRuntime.exitSession(), and OracleRuntime.exitCall()
System.exit() method terminates JVM, preserving no Java state. It does not cause the database session to terminate or the client to disconnect. However, the database session may, and often does, terminate itself immediately afterward.
OracleRuntime.exitSession() also terminates JVM, preserving no Java state. However, it also terminates the database session and disconnects the client.
The behavior of
OracleRuntime.exitCall() varies depending on
OracleRuntime.threadTerminationPolicy(). This method returns a
boolean value. If this value is
true, then any active thread should be terminated, rather than left quiescent, at the end of a database call.
In a shared server process,
In a shadow (dedicated) process, the default value is
false. You can change the value by calling
If you set the value to false, that is the default value, all threads are left quiescent but receive a
ThreadDeathexception for graceful termination.
If the value is true, all threads are terminated abruptly.
In addition, there is another method,
OracleRuntime.callExitPolicy(). This method determines when a call is exited if none of the
System.exit() methods were ever called. The call exit policy can be set to one of the following, using
If set to this value, then as soon as the main thread returns or an uncaught exception occurs on the main thread, all remaining threads, both daemon and non-daemon are:
threadTerminationPolicy()is true, always in shared server mode.
Left quiescent, if
This is the default value. If this value is set, then the call ends when only daemon threads are left running. At this point:
true, always in shared server mode, then the daemon threads are killed.
false, then the daemon threads are left quiescent until the next call. This is the default setting for shadow (dedicated) server mode.
If set to this value, then the call ends only when all threads have either returned or ended due to an uncaught exception. At this point, the call ends regardless of the value of
In Oracle database 9.x and earlier database releases, JVM behaves as if the
OracleRuntime.EXIT_CALL_WHEN_ALL_NON_DAEMON_THREADS_TERMINATE and the
true for both shared and dedicated server processes. This means kill the daemon threads at this point. Also, if
exitCall() were executed, then all threads are killed before the call is ended, in both shared and dedicated server processes.