LoginSignup
0
0

Java21で正式リリースの Virtual Thread を使ってみた(その2)

Last updated at Posted at 2024-02-04

Java19でプレビュー、Java21で正式リリースとなった Virtual Thread(仮想スレッド)を使ってみた。続編。
JNIに追加された関数を使ってみた。

ThreadExecutor.java
package pkg;

public class ThreadExecutor {
	
	/*
	 * JNI C言語ライブラリのロード
	 */
	static {
		System.loadLibrary("JNIVThread");
	}
		
	public static void main(String[] args) throws InterruptedException {

		MyRunnable runnable = new MyRunnable();
		
		// プラットフォームスレッドとして実行する場合
		Thread pthread = Thread.ofPlatform().start(runnable);
		System.out.println("pthread is Virtual ? : " + pthread.isVirtual());
		// スレッドが終了するまで待つ
		pthread.join();
		
		// 仮想スレッドとして実行する場合
		Thread vthread = Thread.ofVirtual().start(runnable);
		System.out.println("vthread is Virthal ? : " + vthread.isVirtual());
		// スレッドが終了するまで待つ
		vthread.join();
	}
}

/**
 * スレッドで実行したい処理
 */
class MyRunnable implements Runnable {

	/*
	 * JNI nativeを付けたメソッドを呼ぶとC言語の関数が呼び出される
	 */
	public native static void writeLog(String message);

	public native static void putThreadObj(Thread thread);

	@Override
	public void run() {
		System.out.println("--> I am Thread. I am Virtual ? : "
			+ Thread.currentThread().isVirtual());
		
		// JNI: C言語モジュールに文字列を渡す
		writeLog("Java");

		// JNI: C言語モジュールに現在のThreadオブジェクトを渡す
		putThreadObj(Thread.currentThread());
		
	}
}
JavaコンパイルとJNIヘッダ生成
# java -version
java version "21.0.2" 2024-01-16 LTS
Java(TM) SE Runtime Environment (build 21.0.2+13-LTS-58)
Java HotSpot(TM) 64-Bit Server VM (build 21.0.2+13-LTS-58, mixed mode, sharing)

# javac -h jni pkg/ThreadExecutor.java

# tree
.
tqq jni
x   mqq pkg_MyRunnable.h
mqq pkg
    tqq MyRunnable.class
    tqq ThreadExecutor.class
    mqq ThreadExecutor.java
pkg_MyRunnable.h (自動生成コード)
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class pkg_MyRunnable */

#ifndef _Included_pkg_MyRunnable
#define _Included_pkg_MyRunnable
#ifdef __cplusplus
extern "C" {
#endif
/*
 * Class:     pkg_MyRunnable
 * Method:    writeLog
 * Signature: (Ljava/lang/String;)V
 */
JNIEXPORT void JNICALL Java_pkg_MyRunnable_writeLog
  (JNIEnv *, jclass, jstring);

/*
 * Class:     pkg_MyRunnable
 * Method:    putThreadObj
 * Signature: (Ljava/lang/Thread;)V
 */
JNIEXPORT void JNICALL Java_pkg_MyRunnable_putThreadObj
  (JNIEnv *, jclass, jobject);

#ifdef __cplusplus
}
#endif
#endif

C言語側の関数定義を作る

pkg_MyRunnable.c
#include "pkg_MyRunnable.h"

JNIEXPORT void JNICALL Java_pkg_MyRunnable_writeLog(JNIEnv *env, jclass class, jstring message)
{
    int jni_ver = (*env)->GetVersion(env);
    switch (jni_ver)
    {
        case JNI_VERSION_21:
            printf("====> JNI_VERSION = JNI_VERSION_21\n");
            printf("====> 0x%08x\n", jni_ver);
            break;
    
        default:
            printf("====> 0x%08x\n", jni_ver);
            break;
    }

    const char *pmsg = (*env)->GetStringUTFChars(env, message, NULL);
    printf("====> C meets : %s\n", pmsg);
    return;
}

JNIEXPORT void JNICALL Java_pkg_MyRunnable_putThreadObj(JNIEnv *env, jclass class, jobject thread)
{
    jboolean jbool = (*env)->IsVirtualThread(env, thread);
    printf("====> IsVirtualThread ? : %hhu\n", jbool);
}
Cコンパイルと共有ライブラリを生成
# gcc -fPIC -shared -I /usr/java/jdk-21/include/ -I /usr/java/jdk-21/include/linux/ -o libJNIVThread.so jni/pkg_MyRunnable.c

# tree
.
tqq jni
x   tqq pkg_MyRunnable.c
x   mqq pkg_MyRunnable.h
tqq libJNIVThread.so
mqq pkg
    tqq MyRunnable.class
    tqq ThreadExecutor.class
    mqq ThreadExecutor.java
実行結果
# java -version
java version "21.0.2" 2024-01-16 LTS
Java(TM) SE Runtime Environment (build 21.0.2+13-LTS-58)
Java HotSpot(TM) 64-Bit Server VM (build 21.0.2+13-LTS-58, mixed mode, sharing)

# java -Djava.library.path=. pkg/ThreadExecutor
pthread is Virtual ? : false
--> I am Thread. I am Virtual ? : false
====> JNI_VERSION = JNI_VERSION_21
====> 0x00150000
====> C meets : Java
====> IsVirtualThread ? : 0
vthread is Virthal ? : true
--> I am Thread. I am Virtual ? : true
====> JNI_VERSION = JNI_VERSION_21
====> 0x00150000
====> C meets : Java
====> IsVirtualThread ? : 1

なるほど。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0