首页 > 代码库 > android NDK编程:使用posix多线程与mutex互斥同步
android NDK编程:使用posix多线程与mutex互斥同步
MainActivity.java
package com.apress.threads; import android.app.Activity; import android.os.Bundle; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; import android.widget.EditText; import android.widget.TextView; public class MainActivity extends Activity { private EditText editThreads; private EditText editIterations; private Button btnStart; private TextView tvLog; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); nativeInit(); editThreads = (EditText) findViewById(R.id.threads_edit); editIterations = (EditText) findViewById(R.id.iterations_edit); btnStart = (Button) findViewById(R.id.start_button); tvLog = (TextView) findViewById(R.id.log_view); btnStart.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { int threads = getNumber(editThreads, 0); int iterations = getNumber(editIterations, 0); if (threads > 0 && iterations > 0) { startThreads(threads, iterations); } } }); } private void startThreads(int threads, int iterations) { // javaThreads(threads, iterations);//使用java的线程来循环 posixThreads(threads, iterations);// 使用posix线程 } private void javaThreads(int threads, final int iterations) { for (int i = 0; i < threads; i++) { final int id = i; new Thread() { @Override public void run() { nativeWorker(id, iterations); super.run(); } }.start(); } } private void onNativeMessage(final String message) { runOnUiThread(new Runnable() { @Override public void run() { tvLog.append(message); tvLog.append("\n"); } }); } private native void posixThreads(int threads, int iterations); // 初始化 private native void nativeInit(); // 释放内存 private native void nativeFree(); // java线程直接调用jni private native void nativeWorker(int id, int iterations); private static int getNumber(EditText editText, int defaultValue) { int value; try { value = http://www.mamicode.com/Integer.parseInt(editText.getText().toString());>com_apress_threads_MainActivity.h:
/* DO NOT EDIT THIS FILE - it is machine generated */ #include <jni.h> /* Header for class com_apress_threads_MainActivity */ #ifndef _Included_com_apress_threads_MainActivity #define _Included_com_apress_threads_MainActivity #ifdef __cplusplus extern "C" { #endif /* * Class: com_apress_threads_MainActivity * Method: posixThreads * Signature: (II)V */ JNIEXPORT void JNICALL Java_com_apress_threads_MainActivity_posixThreads (JNIEnv *, jobject, jint, jint); /* * Class: com_apress_threads_MainActivity * Method: nativeInit * Signature: ()V */ JNIEXPORT void JNICALL Java_com_apress_threads_MainActivity_nativeInit (JNIEnv *, jobject); /* * Class: com_apress_threads_MainActivity * Method: nativeFree * Signature: ()V */ JNIEXPORT void JNICALL Java_com_apress_threads_MainActivity_nativeFree (JNIEnv *, jobject); /* * Class: com_apress_threads_MainActivity * Method: nativeWorker * Signature: (II)V */ JNIEXPORT void JNICALL Java_com_apress_threads_MainActivity_nativeWorker (JNIEnv *, jobject, jint, jint); #ifdef __cplusplus } #endif #endifcom_apress_threads_MainActivity.cpp:
#include <stdio.h> #include <unistd.h> #include <pthread.h> #include "com_apress_threads_MainActivity.h" #include <android/log.h> #define LOG_TAG "LOG FROM JNI" #define LOGW(a) __android_log_write(ANDROID_LOG_WARN,LOG_TAG,a) //传递pthread参数用的结构体 struct NativeWorkerArgs { jint id; jint iterations; }; //回调java的方法 static jmethodID gOnNativeMessage = NULL; static JavaVM* gVm = NULL; //虚拟机引用,作为全局变量 static jobject gObj = NULL; static pthread_mutex_t mutex; //loadLibrary的时候自动调用,在这里获得全局vm引用 jint JNI_OnLoad(JavaVM* vm, void* reserved) { gVm = vm; LOGW("JNI_OnLoad"); return JNI_VERSION_1_4; } void Java_com_apress_threads_MainActivity_nativeInit(JNIEnv *env, jobject obj) { //初始化互斥量 if (0 != pthread_mutex_init(&mutex, NULL)) { //异常 jclass exceptionClazz = env->FindClass("java/lang/RuntimeException"); //抛出 env->ThrowNew(exceptionClazz, "Unable to init mutex--"); } if (NULL == gObj) { gObj = env->NewGlobalRef(obj); } //初始java回调 if (NULL == gOnNativeMessage) { jclass clazz = env->GetObjectClass(obj); gOnNativeMessage = env->GetMethodID(clazz, "onNativeMessage", "(Ljava/lang/String;)V"); if (NULL == gOnNativeMessage) { //异常 jclass exceptionClazz = env->FindClass( "java/lang/RuntimeException"); //抛出 env->ThrowNew(exceptionClazz, "Unable to find method--"); } } } void Java_com_apress_threads_MainActivity_nativeFree(JNIEnv *env, jobject) { //释放全局变量 if (NULL != gObj) { env->DeleteGlobalRef(gObj); gObj = NULL; } //释放互斥量 if (0 != pthread_mutex_destroy(&mutex)) { //异常 jclass exceptionClazz = env->FindClass("java/lang/RuntimeException"); //抛出 env->ThrowNew(exceptionClazz, "Unable to destroy mutex--"); } } //ndk线程执行的代码 void nativeWorker(JNIEnv *env, jobject obj, jint id, jint iterations) { //lock if (0 != pthread_mutex_lock(&mutex)) { //异常 jclass exceptionClazz = env->FindClass("java/lang/RuntimeException"); //抛出 env->ThrowNew(exceptionClazz, "Unable to lock mutex--"); return; } for (jint i = 0; i < iterations; i++) { char message[26]; sprintf(message, "Worker %d:Iteration %d", id, i); //回调java方法 jstring messageString = env->NewStringUTF(message); env->CallVoidMethod(obj, gOnNativeMessage, messageString); if (NULL != env->ExceptionOccurred()) { break; } sleep(1); } //unlock if (0 != pthread_mutex_unlock(&mutex)) { //异常 jclass exceptionClazz = env->FindClass("java/lang/RuntimeException"); //抛出 env->ThrowNew(exceptionClazz, "Unable to unlock mutex--"); } } void Java_com_apress_threads_MainActivity_nativeWorker(JNIEnv *env, jobject obj, jint id, jint iterations) { nativeWorker(env, obj, id, iterations); } //pthread执行的方法 static void* nativeWorkerThread(void* args) { JNIEnv* env = NULL; if (0 == gVm->AttachCurrentThread(&env, NULL)) { NativeWorkerArgs* nativeWorkerAgrs = (NativeWorkerArgs*) args; // nativeWorker(env, gObj, nativeWorkerAgrs->id, nativeWorkerAgrs->iterations); delete nativeWorkerAgrs; gVm->DetachCurrentThread(); } return (void*) 1; } //java调用的,启动多个线程 void Java_com_apress_threads_MainActivity_posixThreads(JNIEnv *env, jobject obj, jint threads, jint iterations) { //thread handlers pthread_t* handles = new pthread_t[threads]; //启动线程 for (jint i = 0; i < threads; i++) { //thread arguments NativeWorkerArgs* nativeWorkArgs = new NativeWorkerArgs(); nativeWorkArgs->id = i; nativeWorkArgs->iterations = iterations; //thread handler int result = pthread_create(&handles[i], NULL, nativeWorkerThread, (void*) nativeWorkArgs); if (result != 0) { //异常 jclass exceptionClazz = env->FindClass( "java/lang/RuntimeException"); //抛出 env->ThrowNew(exceptionClazz, "Unable to create thread--"); return; } } //线程运行结果 for (jint i = 0; i < threads; i++) { void** result = NULL; if (0 != pthread_join(handles[i], result)) { //异常 jclass exceptionClazz = env->FindClass( "java/lang/RuntimeException"); //抛出 env->ThrowNew(exceptionClazz, "Unable to join thread--"); } else { char message[26]; sprintf(message, "Worker %d:return %d", i, result); jstring messageString = env->NewStringUTF(message); env->CallVoidMethod(obj, gOnNativeMessage, messageString); if (NULL != env->ExceptionOccurred()) { return; } } } }代码下载: http://download.csdn.net/detail/hai836045106/7986143
android NDK编程:使用posix多线程与mutex互斥同步
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。