BEA Logo BEA Tuxedo Release 8.0

  BEA ホーム  |  イベント  |  ソリューション  |  パートナ  |  製品  |  サービス  |  ダウンロード  |  ディベロッパ・センタ  |  WebSUPPORT

 

   Tuxedo ホーム   |   BEA Jolt   |   先頭へ   |   前へ   |   次へ   |   目次   |   索引

 


マルチスレッド・アプリケーション

Java ベースのクラス・セットである Jolt は、マルチスレッド・アプリケーションをサポートします。ただし、Java 言語のさまざまなインプリメンテーションは、言語や環境ごとの機能によって異なります。Jolt のプログラマは、次の事項を知っておく必要があります。

「スレッドの状態の種類」では、さまざまな Java のインプリメンテーションでスレッドを使用する際に起こる問題を説明します。また、Jolt プログラムでスレッドを使う例も示します。

注記 多くの場合、Java のインプリメンテーションでは、ノンプリエンティブではなく、プリエンプティブなスレッドが処理されます。プリエンティブなスレッドとノンプリエンティブなスレッドでは、パフォーマンスやプログラミングの条件が大きく異なります。

スレッドの状態の種類

Java 仮想マシンで同時に実行される個々のタスクをスレッドと呼びます。スレッドの状態には、主に RUNNING、RUNNABLE、および BLOCKED があります。

注記 Java 仮想マシン (VM) は、同じ優先度が設定されたスレッドをラウンド・ロビン方式で実行します。

プリエンプティブなスレッド

プリエンティブなスレッドとノンプリエンティブなスレッドでは、Java 仮想マシン (VM) の制御権を放棄するよう実行中のスレッドに対して通知する方法が異なります。プリエンプティブなスレッド環境では通常、ハードウェアのタイマーを周期的にオフになるように設定します。タイマーがオフになると現在のスレッドの状態が RUNNING から RUNNABLE になり、代わりに別のスレッドが実行されます。

ノンプリエンプティブなスレッド

ノンプリエンプティブなスレッド環境のスレッドは、自発的に CPU の制御権を放棄し、RUNNABLE な状態に移行します。Java 言語クラス内の多くのメソッドには、制御権を自発的に放棄するコードが含まれています。これらのコードは通常、長い処理時間のかかる操作に関連付けられています。たとえば、ネットワークからデータを読み込むと、スレッドは通常パケットの到着を待ちます。イベントやリソースが利用可能になるまで待機するスレッドは BLOCKED の状態です。イベントが発生するか、またはリソースが利用できるようになると、そのスレッドは RUNNABLE になります。

Jolt をノンプリエンプティブなスレッドで使う

ノンプリエンプティブなスレッド環境の仮想マシン (例 : Sun Solaris) で Jolt ベースの Java プログラムを実行する場合、次のいずれかが行われる必要があります。

典型的な方法として、実行するコードが長い部分または時間がかかりそうなループのすべてで次の呼び出しを行います。

Thread.currentThread.yield();

このメッセージを送信しないと、Jolt ライブラリで使用されるスレッドはスケジューリングされず、Jolt 操作に不具合が生じます。

ノンプリエンプティブなスレッドを使用する仮想マシンとして知られている唯一のマシンは、Sun プラットフォーム用の Java Developer’s Kit (JDK) です。アプレットを JDK 1.3 で実行するには、yield メッセージを必ず送信してください。既に述べたように、メソッドの中には yield を含むものがあります。例外は System.in.readメソッドです。このメッセージはスレッドの切り替えを行いません。これらのメッセージを使用する代わりに、yield を明示的に使用することをお勧めします。

非同期的な処理を行うためにスレッドを使う

スレッドを使用して、BEA Tuxedo のtpacall() に似た非同期的な処理を Jolt で行うことができます。この機能があれば、非同期的にサービスを要求する機能は必要ありません。この機能が使えるのは Jolt がスレッド・セーフであるためです。たとえば、Jolt クライアント・アプリケーションは、BEA Tuxedo サービスにリクエストを送信するスレッドを開始した後で直ちに BEA Tuxedo サービスに別のリクエストを送信する別のスレッドを開始することができます。したがって、Jolt による tpacall() の呼び出しが同期的であっても、2 つのスレッドが同時に実行されているため、アプリケーションは非同期的です。

Jolt でスレッドを使用する

Jolt クライアント側のプログラムまたはアプレットは完全にスレッド・セーフです。Jolt がサポートするマルチスレッド・アプリケーションでは、クライアント側に次の特徴があります。

次のコード例は、Jolt アプリケーションで 2 つのスレッドを使用する方法を示したものです。

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;
         // 必要な属性を設定
dattr = new JoltSessionAttributes();
dattr.setString(dattr.APPADDRESS,"//bluefish:8501");
         // ドメインをインスタンス化する
// 認証レベルを調べる
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);
}
}
}

 

先頭へ戻る 前のトピックへ 次のトピックへ