对于原生代码使用Java线程的优缺点

来源:互联网 发布:吉利知豆好不好 编辑:程序博客网 时间:2024/05/21 15:55

   对于原生的代码使用Java线程与原生的线程相比有一下的优点:

   它是很容易建立的。

   在原生代码不需要任何改变

  它不需要明确的附加到这虚拟机,Java线程已经是Java平台的一部分。原生代码和Java代码通信使用线程指定的JNIEnv接口指针。

  方法被提供通过java.lang.Thread类能够被用无缝的和线程实例沟通。

  除了它的优势,这Java线程有这主要短缺与原生线程相比当对于多线程的原生代码:

     假定这逻辑分配任务到线程是Java代码的部分,因为在原生区域来创建Java线程没有API。

    假定这原生代码是线程安全的,因为基于Java的线程是透明对于这原生代码。

   原生代码不能从其他同伴编程内容和组件获益,例如信号量,因为没有API对于原生代码。

   原生代码运行在一个单独的新车不能交流或者直接分享资源。

POSIX 线程

POSIX线程,也是作为简单Pthreads,是一个POSIX标准对于线程。

在原生代码中使用POSIX线程

    这POSIX线程API通过pthread.h头文件被定义。为了使用POSIX线程在原生代码,这头文件需要首先被包含。

   #include<pthread.h>

   这Android实现POSIX线程是BIONIC标准C库 的一部分。不像其他的平台,在编译时不需要连接其他的额外库。

  使用pthread_create创建线程

  int pthread_create(pthread_t* thread,pthread_attr_t const* attr,void* (*start_routine)(void*),
void* arg);

                    这个函数的参数是:

     一个thread_t类型的指针变量被函数利用来返回对于这新线程的的句柄。

    以pthread_attr_t结构体的指针是新线程的属性。栈的基地址,栈的大小,防卫大小,调度策略和对于新线程的调度游戏级通过这个属性来指定。你将学到一些属性。使用默认属性时,使用NULL。

   一个函数指针对于开始路径对于这个线程。这个开始路径函数的签名应该看下面:

     void* start_rountine(void* args);

  这开始路径去线程参数作为一个空指针,和它返回作为一个空指针作为结果。

任何参数应该被传递给开始路径当线程以一个void指针个等到执行。如果没有承诺书需要传递,返回NULL。

   pthread_create函数将返回0;否则他将返回一个错误代码。

有多重的方法来获得Java VM接口指针。这容易和恰当的方式做这通过这JNI_OnLoad函数。这个函数得到自动触发由虚拟机当一个共享库被加载。这个函数去Java Vm接口指针作为它的一个参数。如下,增加这JNI_OnLoad函数到本地为了存储Java Vm接口指针在gVm全局变量被地你故意在上一步。

#include <pthread.h>

// Native worker thread arguments
struct NativeWorkerArgs
{
jint id;
jint iterations;
};

// Method ID can be cached
static jmethodID gOnNativeMessage = NULL;
// Java VM interface pointer
static JavaVM* gVm = NULL;
// Global reference to object
static jobject gObj = NULL;
void Java_com_apress_threads_MainActivity_nativeInit (
JNIEnv* env,
jobject obj)

 

 

      jint JNI_OnLoad(JavaVM* vm,void* reserved)

     {

         //Cache 这JavaVM接口指针

        gVm=vm;

        return JNI_VERSION_1_4;

               

     }

 

 

void Java_com_apress_threads_MainActivity_nativeInit (
JNIEnv* env,
jobject obj)
{
// If object global reference is not set
if (NULL == gObj)
{
// Create a new global reference for the object
gObj = env->NewGlobalRef(obj);
if (NULL == gObj)
{
goto exit;
}
}
// If method ID is not cached
if (NULL == gOnNativeMessage)
...
exit:
return;
}

 

void Java_com_apress_threads_MainActivity_nativeFree (
JNIEnv* env,
jobject obj)
{
// If object global reference is set
if (NULL != gObj)
{
// Delete the global reference
env->DeleteGlobalRef(gObj);
gObj = NULL;
}
}
...

 

 

static void* nativeWorkerThread (void* args)
{
JNIEnv* env = NULL;
// Attach current thread to Java virtual machine
// and obrain JNIEnv interface pointer
if (0 == gVm->AttachCurrentThread(&env, NULL))
{
// Get the native worker thread arguments
NativeWorkerArgs* nativeWorkerArgs = (NativeWorkerArgs*) args;
// Run the native worker in thread context
Java_com_apress_threads_MainActivity_nativeWorker(env,
gObj,
nativeWorkerArgs->id,
nativeWorkerArgs->iterations);
// Free the native worker thread arguments
delete nativeWorkerArgs;
// Detach current thread from Java virtual machine
gVm->DetachCurrentThread();
}
return (void*) 1;
}

    从线程中返回结果:

当他们终止时,线程能够返回一个结果。通过这空指针这能够被获得从这线程开始路径。在上一个例子中,这Java_com_apress_threads_MainActivity_PosixThreads函数被设计来直接返回在执行这线程后。这个函数被修改来等待线程来完成他们的工作和返回。一个函数能够等待一个线程通过使用pthread_join函数来终止。

   int pthread_join(pthread_t thread,void** ret_val);

这Pthread_join函数的参数:

       线程句柄有pthread_create函数对于目标线程的返回。

      获得这个返回结果从开始路径的指针。

它阻止这调用线程的执行直到这目标线程终止。如果这ret_val不是NULL,这个函数将设置ret_val指针值返回这开始的路径。pthread_join返回0;否则返回错误代码。

 

 

 

    
0 0
原创粉丝点击