JDK 1.1 開発ガイド (Solaris 編)

演算を並列的に処理する Java アプリケーションの作成


注意 - 注意 -

通常は、ネイティブメソッドを使用して、thr_setconcurrency(3T) などの Solaris 固有の機能にアクセスしないようにしてください。アプリケーションが Solaris 用のみに限定され、100% Pure Java に準拠しなくなってしまうためです。



注 -

Java アプリケーションで thr_setconcurrency (3T)が必要になる場合はほとんどありません。必要になる場合としては、たとえば、ダミースレッドを使用して実行を繰り返すデモアプリケーション、あるいは行列の乗算や並列化されたグラフィックス計算などの演算アプリケーションなどが考えられます。


thr_setconcurrency(3T) の使用例

並列化された行列の乗算などの演算アプリケーションでは、ネイティブメソッドを使用して、thr_setconcurrency(3T) を呼び出す必要があります。これは、Java アプリケーションから同時に使用可能な資源を十分に使用して、複数のプロセッサを活用できるようにするためです。この方法は、大部分の Java アプリケーションやアプレットには必要ありません。次に、ネイティブメソッドを使用して thr_setconcurrency(3T) を呼び出す例を示します。

1 つ目の要素は、MPtest_NativeTSetconc() を使用する Java アプリケーション、MPtest.java です。このアプリケーションは、1 行ずつ識別情報を表示し、10,000,000 回ループして演算処理をシミュレートするスレッドを 10 個作成します。


例 3-3 MPtest.java


import java.applet.*;
import java.io.PrintStream;
import java.io.*;
import java.net.*;
 
class MPtest {
   static native void NativeTSetconc();
   static public int THREAD_COUNT = 10;
   public static void main (String args[]) {
      int i;
 
// sysconf (_SC_NPROCESSORS_ONLN) に
// Solaris での並列処理を設定
      NativeTSetconc();
// スレッドを開始
      client_thread clients[] = new client_thread[ THREAD_COUNT ];
      for ( i = 0; i < THREAD_COUNT; ++i ){
         clients[i] = new client_thread(i, System.out);
         clients[i].start();
      }  
   }
 
   static { System.loadLibrary("NativeThreads"); 
}
class client_thread extends Thread {
   PrintStream out;
   public int LOOP_COUNT = 10000000;
   client_thread(int num, PrintStream out){
      super( "Client Thread" + Integer.toString( num ) );
      this.out = out;
      out.println("Thread " + num);
   }
   public void run () {
      for( int i = 0; i < this.LOOP_COUNT  ; ++i ) {;
				}
		}
}

2 つ目の要素は、javah(1) ユーティリティを使用して、MPtest.java から作成した C スタブファイルの MPtest.c です。このファイルを作成するには、次のようにコマンドを実行します。


% javac MPtest.java
% javah -stubs MPtest

3 つ目の要素は、同じく javah(1) ユーティリティを使用して、MPtest.java から作成した C ヘッダーファイルの MPtest.h です。


% javah MPtest

4 つ目の要素は、C ライブラリインタフェースへの呼び出しを行う C 関数の NativeThreads.c です。


#include <thread.h>
#include <unistd.h>
#include <jni.h>
JNIEXPORT void JNICALL Java_MPtest_NativeTSetconc(JNIEnv *env, jclass obj) {
		thr_setconcurrency(sysconf(_SC_NPROCESSORS_ONLN));
}

次のようなメークファイルを使用すると、4 つのファイルから、MPtest.class という Java アプリケーションを簡単に作成することができます。


例 3-4 MPtest.class を生成する makefile


# make は次の処理を行います。
# 1. make MPtest を実行
# 2. thr_setconcurrency(_SC_NPROCESSORS_ONLN) へのネイティブ呼び出しを
#    取り込むために NativeThreads.c を作成
# 3. make lib を実行
#
# これで、LD_LIBRARY_PATH および CLASSPATH を . に設定して
#、java MPtest を実行できるようになる
 
JAVA_HOME=/usr/java
JH_INC1=${JAVA_HOME}/include
JH_INC2=${JAVA_HOME}/include/solaris
 
MPtest:
		${JAVA_HOME}/bin/javac MPtest.java 
		(CLASSPATH=. ; export CLASSPATH ; ${JAVA_HOME}/bin/javah -stubs MPtest)
		(CLASSPATH=. ; export CLASSPATH ; ${JAVA_HOME}/bin/javah -jni MPtest)
 
lib:
		cc -G -I${JH_INC1} -I${JH_INC2} NativeThreads.c -lthread ¥
		-o libNativeThreads.so
 
clean:
		rm -rf *.class libNativeThreads.so *.h MPtest.c