BEA Logo BEA Tuxedo Release 7.1

  Corporate Info  |  News  |  Solutions  |  Products  |  Partners  |  Services  |  Events  |  Download  |  How To Buy

 

   Tuxedo Doc Home   |   Jolt   |   Topic List   |   Previous   |   Next   |   Contents   |   Index

   Using BEA Jolt

Multithreaded Applications

As a Java-based set of classes, Jolt supports multithreaded applications; however, various implementations of the Java language differ with respect to certain language and environment features. Jolt programmers need to be aware of the following:

Threads of Control describes the issues arising from using threads with different Java implementations and is followed by an example of the use of threads in a Jolt program.

Note: Most Java implementations provide preemptive rather than non-preemptive threads. The difference between these two models can lead to very different performance and programming requirements.

Threads of Control

Each concurrently operating task in the Java virtual machine is a thread. Threads exist in various states, the important ones being RUNNING, RUNNABLE, or BLOCKED.

Preemptive Threading

The main performance difference between the two threading models arises in telling a running thread to relinquish control of the Java VM. In a preemptive threading environment, the usual procedure is to set a hardware timer that goes off periodically. When the timer goes off, the current thread is moved from the RUNNING to the RUNNABLE state, and another thread is chosen to run.

Non-preemptive Threading

In a non-preemptive threading environment, a thread must volunteer to give up control of the CPU and move to the RUNNABLE state. Many methods in the Java language classes contain code that volunteers to give up control, and are typically associated with actions that might take a long time. For example, reading from the network generally causes a thread to wait for a packet to arrive. A thread that is waiting on the availability of some event or resource is in the BLOCKED state. When the event occurs or the resource becomes available, the thread becomes RUNNABLE.

Using Jolt with Non-Preemptive Threading

If your Jolt-based Java program is running on a non-preemptive threading Virtual Machine (such as Sun Solaris), the program must either:

The typical usage is to make the following call in all long-running code segments or potentially time-consuming loops:

Thread.currentThread.yield();

Without sending this message, the threads used by the Jolt Library may never get scheduled and, as such, the Jolt operation is impaired.

The only virtual machine known to use non-preemptive threading is the Java Developer's Kit (JDK version 1.0, 1.0.1, 1.0.2) machine running on a Sun platform. If you want your applet to work on JDK 1.0, you must make sure to send the yield messages. As mentioned earlier, some methods contain yields. An important exception is the System.in.read method. This method does not cause a thread switch. Rather than rely on these messages, we suggest using yields explicitly.

Using Threads for Asynchronous Behavior

You can use threads in Jolt to get asynchronous behavior that is analogous to the tpacall() function in BEA Tuxedo. With this capability, you do not need an asynchronous service request function. You can get this functionality because Jolt is thread-safe. For example, the Jolt client application can start one thread that sends a request to a BEA Tuxedo service function and then immediately start another thread that sends another request to a BEA Tuxedo service function. So even though the Jolt tpacall() is synchronous, the application is asynchronous because the two threads are running at the same time.

Using Threads with Jolt

A Jolt client-side program or applet is fully thread-safe. Jolt support of multithreaded applications includes the following client characteristics:

The following listing illustrates the use of two threads in a Jolt application.

Using Multiple Threads with Jolt (ThreadBank.java)


/* Copyright 1996 BEA Systems, Inc.  All Rights Reserved */
import bea.jolt.*;
public class ThreadBank
{
public static void main (String [] args)
{
JoltSession session;
try
{
JoltSessionAttributes dattr;
String userName = null;
String userPasswd = null;
String appPasswd = null;
String userRole = null;

         // fill in attributes required
dattr = new JoltSessionAttributes();
dattr.setString(dattr.APPADDRESS,"//bluefish:8501");

         // instantiate domain
// check authentication level
switch (dattr.checkAuthenticationLevel())
{

         case JoltSessionAttributes.NOAUTH:
System.out.println("NOAUTH\n");
break;
case JoltSessionAttributes.APPASSWORD:
appPasswd = "myAppPasswd";
break;
case JoltSessionAttributes.USRPASSWORD:
userName = "myName";
userPasswd = "mySecret";
appPasswd = "myAppPasswd";
break;
}
dattr.setInt(dattr.IDLETIMEOUT, 60);
session = new JoltSession (dattr, userName, userRole,
userPasswd, appPasswd);
T1 t1 = new T1 (session);
T2 t2 = new T2 (session);

         t1.start();
t2.start();

         Thread.currentThread().yield();
try
{
while (t1.isAlive() && t2.isAlive())
{
Thread.currentThread().sleep(1000);

}
}
catch (InterruptedException e)
{
System.err.println(e);
if (t2.isAlive())
{
System.out.println("job 2 is still alive");
try
{
Thread.currentThread().sleep(1000);
}
catch (InterruptedException e1)
{
System.err.println(e1);
}
}
else if (t1.isAlive())
{ System.out.println("job1 is still alive");
try
{
Thread.currentThread().sleep(1000);
}
catch (InterruptedException e1)
{
System.err.println(e1);
}
}
}
session.endSession();
}
catch (SessionException e)
{
System.err.println(e);
}
finally
{
System.out.println("normal ThreadBank term");
}
}
}

class T1 extends Thread
{
JoltSession j_session;
JoltRemoteService j_withdrawal;

   public T1 (JoltSession session)
{
j_session=session;
j_withdrawal= new JoltRemoteService("WITHDRAWAL",j_session);
}
public void run()
{
j_withdrawal.addInt("ACCOUNT_ID",10001);
j_withdrawal.addString("SAMOUNT","100.00");
try
{
System.out.println("Initiating Withdrawal from account 10001");
j_withdrawal.call(null);
String W = j_withdrawal.getStringDef("SBALANCE","-1.0");
System.out.println("-->Withdrawal Balance: " + W);
}
catch (ApplicationException e)
{
e.printStackTrace();
System.err.println(e);
}
}
}

class T2 extends Thread
{
JoltSession j_session;
JoltRemoteService j_deposit;

   public T2 (JoltSession session)
{
j_session=session;
j_deposit= new JoltRemoteService("DEPOSIT",j_session);
}
public void run()
{
j_deposit.addInt("ACCOUNT_ID",10000);
j_deposit.addString("SAMOUNT","100.00");
try
{
System.out.println("Initiating Deposit from account 10000");
j_deposit.call(null);
String D = j_deposit.getStringDef("SBALANCE","-1.0");
System.out.println("-->Deposit Balance: " + D);
}
catch (ApplicationException e)
{
e.printStackTrace();
System.err.println(e);
}
}
}