原生线程
1 示例项目
2 java线程
创建项目NativeThread
添加原生支持android tools--->add Native support
创建用户界面: activity_main.xml文件
<LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".MainActivity">
<EditText
android:id="@+id/edt_threads"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:ems="10"
android:focusable="true"
android:hint="@string/threads_edit"
android:inputType="number">
</EditText>
<EditText
android:id="@+id/edt_iterations"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:ems="10"
android:hint="@string/iterations_edit"
android:inputType="number"/>
<Button
android:id="@+id/btn_start"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/btn_start"/>
<ScrollView
android:id="@+id/scrollview"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:id="@+id/txt_log"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
</ScrollView>
</LinearLayout>
字符串资源: string.xml文件
<?xmlversion="1.0"encoding="utf-8"?>
<resources>
<stringname="app_name">NativeThreads</string>
<stringname="action_settings">Settings</string>
<stringname="hello_world">NativeThreads</string>
<stringname="threads_edit">Thread count</string>
<stringname="iterations_edit">Iteration count</string>
<stringname="btn_start">Start Threads</string>
</resources>
MainActivity.java文件

/**
* 原生线程
* 
* @version
* 
* @Description:
* 
* @author <ahref="mailto:zhenhuayue@sina.com">Retacn</a>
* 
* @since 2014-7-9
* 
*/
public class MainActivity extends Activity {
 /* start button */
 private Buttonbtn_start;
 /* threads edit */
 private EditTextedt_threads;
 /* iterations edit*/
 private EditTextedt_iterations;
 /* log textView */
 private TextViewtxt_log;

 @Override
 protected voidonCreate(Bundle savedInstanceState) {
 super.onCreate(savedInstanceState);
 setContentView(R.layout.activity_main);
 // 本地方法 初始化原生代码
 nativeInit();

 // 实例化控件
 findView();
 }

 /**
 * 实例化控件
 */
 private voidfindView() {
 btn_start =(Button) this.findViewById(R.id.btn_start);
 btn_start.setOnClickListener(newOnClickListener() {

 @Override
 publicvoid onClick(View v) {
 intthreads = NativeThreadUtils.getIntNumber(edt_threads.getText().toString(), 0);
 intiterations = NativeThreadUtils.getIntNumber(edt_iterations.getText().toString(),0);
 if(threads > 0 && iterations > 0) {
 //启动给定个数的线程进行迭代
 startThreads(threads,iterations);
 }
 }
 });
 edt_threads =(EditText) this.findViewById(R.id.edt_threads);
 edt_iterations= (EditText) this.findViewById(R.id.edt_iterations);
 txt_log =(TextView) this.findViewById(R.id.txt_log);

 }

 /**
 * 启动给定个数的线程进行迭代
 * 
 * @param threads
 *线程数
 * @param iterations
 *迭代数
 */
 private voidstartThreads(int threads, final int iterations) {
 javaThreads(threads,iterations);
 }

 /**
 * 使用基于 java的线程
 * 
 * @param threads
 * @param iterations
 */
 private voidjavaThreads(int threads, final int iterations) {
 // 为每一个worker创建军基于java的线程
 for (int i = 0; i < threads; i++) {
 finalint id = i;
 Threadthread = new Thread() {
 @Override
 publicvoid run() {
 //
 nativeWorker(id,iterations);
 }
 };
 thread.start();
 }
 }

 /**
 * 原生线程回调
 * 
 * @param message
 *原生消息
 */
 private voidonNativeMessage(final String message) {
 runOnUiThread(newRunnable() {

 @Override
 publicvoid run() {
 txt_log.append(message);
 txt_log.append("\n");
 }
 });
 }

 @Override
 public boolean onCreateOptionsMenu(Menumenu) {
 getMenuInflater().inflate(R.menu.main,menu);
 return true;
 }

 @Override
 protected voidonDestroy() {
 // 释放原生资源
 nativeFree();
 super.onDestroy();
 }

 // 声明本地方法
 /* 初始化本地方法 */
 private native voidnativeInit();

 /* 释放原生资源 */
 private native voidnativeFree();

 /**
 * 原生worker
 * 
 * @param id
 * @param iterations
 */
 private native voidnativeWorker(int id, int iterations);

 /**
 * 加载本地库
 */
 static {
 System.loadLibrary("NativeThreads");
 }
}
生成c++头文件
Projectexplorer--->MainActivity.java--->run--->external tools--->generatec and c++ header file
将会在jni目录下生成cn_yue_nativethreads_MainActivity.h头文件,示例代码如下:
/* DO NOT EDIT THIS FILE - it is machine generated */
#include<jni.h>
/* Header for class cn_yue_nativethreads_MainActivity */
#ifndef _Included_cn_yue_nativethreads_MainActivity
#define _Included_cn_yue_nativethreads_MainActivity
#ifdef __cplusplus
extern"C"
#endif
#undef cn_yue_nativethreads_MainActivity_MODE_PRIVATE
#define cn_yue_nativethreads_MainActivity_MODE_PRIVATE0L
#undefcn_yue_nativethreads_MainActivity_MODE_WORLD_READABLE
#definecn_yue_nativethreads_MainActivity_MODE_WORLD_READABLE 1L
#undefcn_yue_nativethreads_MainActivity_MODE_WORLD_WRITEABLE
#definecn_yue_nativethreads_MainActivity_MODE_WORLD_WRITEABLE 2L
#undef cn_yue_nativethreads_MainActivity_MODE_APPEND
#define cn_yue_nativethreads_MainActivity_MODE_APPEND32768L
#undefcn_yue_nativethreads_MainActivity_MODE_MULTI_PROCESS
#definecn_yue_nativethreads_MainActivity_MODE_MULTI_PROCESS 4L
#undefcn_yue_nativethreads_MainActivity_BIND_AUTO_CREATE
#definecn_yue_nativethreads_MainActivity_BIND_AUTO_CREATE 1L
#undefcn_yue_nativethreads_MainActivity_BIND_DEBUG_UNBIND
#define cn_yue_nativethreads_MainActivity_BIND_DEBUG_UNBIND2L
#undefcn_yue_nativethreads_MainActivity_BIND_NOT_FOREGROUND
#definecn_yue_nativethreads_MainActivity_BIND_NOT_FOREGROUND 4L
#undefcn_yue_nativethreads_MainActivity_BIND_ABOVE_CLIENT
#define cn_yue_nativethreads_MainActivity_BIND_ABOVE_CLIENT8L
#undefcn_yue_nativethreads_MainActivity_BIND_ALLOW_OOM_MANAGEMENT
#definecn_yue_nativethreads_MainActivity_BIND_ALLOW_OOM_MANAGEMENT 16L
#undefcn_yue_nativethreads_MainActivity_BIND_WAIVE_PRIORITY
#define cn_yue_nativethreads_MainActivity_BIND_WAIVE_PRIORITY32L
#undefcn_yue_nativethreads_MainActivity_BIND_IMPORTANT
#definecn_yue_nativethreads_MainActivity_BIND_IMPORTANT 64L
#undefcn_yue_nativethreads_MainActivity_BIND_ADJUST_WITH_ACTIVITY
#define cn_yue_nativethreads_MainActivity_BIND_ADJUST_WITH_ACTIVITY64L
#undefcn_yue_nativethreads_MainActivity_CONTEXT_INCLUDE_CODE
#definecn_yue_nativethreads_MainActivity_CONTEXT_INCLUDE_CODE 1L
#undefcn_yue_nativethreads_MainActivity_CONTEXT_IGNORE_SECURITY
#define cn_yue_nativethreads_MainActivity_CONTEXT_IGNORE_SECURITY2L
#undefcn_yue_nativethreads_MainActivity_CONTEXT_RESTRICTED
#definecn_yue_nativethreads_MainActivity_CONTEXT_RESTRICTED 4L
#undefcn_yue_nativethreads_MainActivity_RESULT_CANCELED
#definecn_yue_nativethreads_MainActivity_RESULT_CANCELED 0L
#undef cn_yue_nativethreads_MainActivity_RESULT_OK
#define cn_yue_nativethreads_MainActivity_RESULT_OK -1L
#undefcn_yue_nativethreads_MainActivity_RESULT_FIRST_USER
#definecn_yue_nativethreads_MainActivity_RESULT_FIRST_USER 1L
#undefcn_yue_nativethreads_MainActivity_DEFAULT_KEYS_DISABLE
#definecn_yue_nativethreads_MainActivity_DEFAULT_KEYS_DISABLE 0L
#undefcn_yue_nativethreads_MainActivity_DEFAULT_KEYS_DIALER
#define cn_yue_nativethreads_MainActivity_DEFAULT_KEYS_DIALER1L
#undefcn_yue_nativethreads_MainActivity_DEFAULT_KEYS_SHORTCUT
#definecn_yue_nativethreads_MainActivity_DEFAULT_KEYS_SHORTCUT 2L
#undefcn_yue_nativethreads_MainActivity_DEFAULT_KEYS_SEARCH_LOCAL
#definecn_yue_nativethreads_MainActivity_DEFAULT_KEYS_SEARCH_LOCAL 3L
#undefcn_yue_nativethreads_MainActivity_DEFAULT_KEYS_SEARCH_GLOBAL
#definecn_yue_nativethreads_MainActivity_DEFAULT_KEYS_SEARCH_GLOBAL 4L
/*
* 初始化本地方法
* Class: cn_yue_nativethreads_MainActivity
* Method: nativeInit
* Signature: ()V
*/
JNIEXPORT void JNICALL  Java_cn_yue_nativethreads_MainActivity_nativeInit(
JNIEnv *,  jobject);
/*
* 释放本地资源
* Class: cn_yue_nativethreads_MainActivity
* Method: nativeFree
* Signature: ()V
*/
JNIEXPORT void JNICALL  Java_cn_yue_nativethreads_MainActivity_nativeFree(
JNIEnv *,  jobject);
/*
* 原生worker
* Class: cn_yue_nativethreads_MainActivity
* Method: nativeWorker
* Signature: (II)V
*/
JNIEXPORT void JNICALL  Java_cn_yue_nativethreads_MainActivity_nativeWorker(
JNIEnv *,  jobject, jint,  jint);
#ifdef __cplusplus
}
#endif
#endif
实现原生函数
/*
*cn_yue_nativethreads_MainActivity.cpp
*
* Created on: 2014-7-9
* Author: retacn
* 
*/
#include<stdio.h>
#include<unistd.h>
#include"cn_yue_nativethreads_MainActivity.h"
//方法ID能被缓存
staticjmethodID
/*
* 初始化本地方法
* Class: cn_yue_nativethreads_MainActivity
* Method: nativeInit
* Signature: ()V
*/
void JNICALL Java_cn_yue_nativethreads_MainActivity_nativeInit(JNIEnv
jobject
//如果方法没有被缓存
 if (NULL == gOnNativeMessage) {
//从对象中取得类
jclass
//为回调方法id
 "onNativeMessage", "(Ljava/lang/String;)V");
//如果没有找到方法
 if (NULL == gOnNativeMessage) {
//获取异常类
jclass
"java/lang/RuntimeException");
//抛出异常
"Unable to find methond");
 }
 }
}
/*
* 释放本地资源
* Class: cn_yue_nativethreads_MainActivity
* Method: nativeFree
* Signature: ()V
*/
void JNICALL Java_cn_yue_nativethreads_MainActivity_nativeFree(JNIEnv
jobject
}
/*
* 原生worker
* Class: cn_yue_nativethreads_MainActivity
* Method: nativeWorker
* Signature: (II)V
*/
void JNICALL Java_cn_yue_nativethreads_MainActivity_nativeWorker(JNIEnv
jobject obj,  jint id, jint
//循环给定的迭代次数
 for (jint
//准备消息
 char message[26];
 sprintf(message, "worker %d: iteration %d", id, i);
//来自c字符串的消息
jstring
//调用原生消息方法
 env->CallVoidMethod(obj,gOnNativeMessage, messageString);
//检查是否发和异常
 if (NULL != env->ExceptionOccurred()) {
 break;
 }
 sleep(1);
 }
}
更新android.mk构建脚本
LOCAL_PATH := $(call my-dir)
include$(CLEAR_VARS)
LOCAL_MODULE := NativeThreads
LOCAL_SRC_FILES :=cn_yue_nativethreads_MainActivity.cpp
include$(BUILD_SHARED_LIBRARY)
3 posix线程
在原生代码中使用posix线程,需要添加#include <pthread.h>
//成功返回0
Int pthread_create(pthread_t thread,//用该指针返回新线程的句柄
 pthread_attr_tconst* cttr,//新线程属性
 void*(*start_routine) (void*),//指向中线程启动程序的指针
 void*arg);//
在示例中使用posix线程
A 声明原生方法
/* 使用原生posix线程 */
 privatenativevoid posixThreads(int threads, int iterations);
B 重新生成头文件
/*
* Class: cn_yue_nativethreads_MainActivity
* Method: posixThreads
* Signature: (II)V
*/
JNIEXPORT void JNICALL  Java_cn_yue_nativethreads_MainActivity_posixThreads
JNIEnv *, jobject, jint, jint);
C 更新原生代码 
 添加#include<pthread.h>
 定义启动参数结构体
/*原生线程参数*/
structNativeWorkerArgs
jintid;
jintiterations;
};
 全局变量保存java vm和对象实例的全局引用
/*java虚拟机接口指针*/
staticJavaVM* gVm = NULL;
/*对象的全局引用*/
staticjobject
...
/**
* 取得java虚拟机接口指针
*/
jintJNI_OnLoad(JavaVM* vm, void* reserved) {
//缓存java虚拟机接口批针
 gVm = vm;
 return JNI_VERSION_1_4;
}
voidJava_cn_yue_nativethreads_MainActivity_nativeInit(JNIEnv
jobject
//为对象实例创建一个全局引用
 if (NULL == gObj) {
//创建全局变量
 gObj =env->NewGlobalRef(obj);
 if (NULL == gObj) {
 goto exit;
 }
 }
...
}
 在freeNative中删除全局引用
//删除全局引用
 if (NULL != gObj) {
 env->DeleteGlobalRef(gObj);
 gObj = NULL;
 }
 为原生worker线程添加启动程序
/**
* 为原生worker添加启动程序
*/
staticvoid* nativeWorkerThread(void* args) {
JNIEnv* env = NULL;
//将当前线程符加到java虚拟机上
 if (0 == gVm->AttachCurrentThread(&env,NULL)) {
//取得原生worker线程参数
NativeWorkerArgs* nativeWorkerArgs = (NativeWorkerArgs*) args;
//在线程上下文中运行wroker
 Java_cn_yue_nativethreads_MainActivity_nativeWorker(env,gObj,
id,nativeWorkerArgs->iterations);
//释放原生线程worker线程参数
 delete nativeWorkerArgs;
//从java虚拟机中分离当前线程
 gVm->DetachCurrentThread();
 }
 return (void*) 1;
}
 实现posixThread原生方法
/*
* posix线程
* Class: cn_yue_nativethreads_MainActivity
* Method: posixThreads
* Signature: (II)V
*/
voidJava_cn_yue_nativethreads_MainActivity_posixThreads(JNIEnv* env,
jobject obj,  jint threads, jint
//为每一个worker创建一个posix线程
 for (jint
NativeWorkerArgs* nativeWorkerArgs = newNativeWorkerArgs();
id= i;
iterations
pthread_t
//创建一个新线程
 int result = pthread_create(&thread, NULL, nativeWorkerThread,
 (void*) nativeWorkerArgs);
 if (0 != result) {
//获取异常类
jclass
"java/lang/RuntimeException");
//抛出异常
"Unable to createthread!");
 }
 }
}
4 从posix线程返回结果
Java_cn_yue_nativethreads_MainActivity_posixThreads是在线程执行后立即返回,通过pthread_join可以合其在线程结束后返回
//函数原型 成功返回结果为0
intpthread_join(pthread_t
void ** ret_val);//指向空指针的指针,从启动程序中取得返回值
更改示例程序
/*
* posix线程
* Class: cn_yue_nativethreads_MainActivity
* Method: posixThreads
* Signature: (II)V
*/
voidJava_cn_yue_nativethreads_MainActivity_posixThreads(JNIEnv* env,
jobject obj,  jint threads, jint
//线程句柄
pthread_t* handles = newpthread_t(threads);
//为每一个worker创建一个posix线程
 for (jint
NativeWorkerArgs* nativeWorkerArgs = newNativeWorkerArgs();
id= i;
iterations
pthread_t
//创建一个新线程
 int result = pthread_create(&handles[i], NULL, nativeWorkerThread,
 (void*) nativeWorkerArgs);
 if (0 != result) {
//获取异常类
jclass
"java/lang/RuntimeException");
//抛出异常
"Unable to createthread!");
 goto exit;
 }
 }
//等待线程终止
 for (jint
 void* result = NULL;
//连接每个句柄
 if (0 != pthread_join(handles[i], &result)) {
//获取异常类
jclass
"java/lang/RuntimeException");
//抛出异常
"Unable to jointhread!");
 } else {
//准备message
 char message[26];
 sprintf(message, "worker %d returned %d", i, result);
//
jstring
//调用原生消息方法
 env->CallVoidMethod(obj,gOnNativeMessage, messageString);
//检查是否产生异常
 if (NULL != env->ExceptionOccurred()) {
 goto exit;
 }
 }
 }
 exit: return;
}
5 posix线程同步
两种最常用的同步机制:
A 互斥锁(mutexes) pthread_mutex_t展示互斥锁到原生代码
使用互斥锁同步posix线程
初始化互斥锁
intpthread_mutex_init(pthread_mutex_t
constpthread_mutexattr_t
如果第二个参数为空,则使用默认属性如下:
#define__PTHREAD_MUTEX_INIT_VALUE0
#definePTHREAD_MUTEX_INITIALIZER
如果初始化成功互斥锁处于打开状态 ,返回值为0
锁定互斥锁
intpthread_mutex_lock(pthread_mutex_t
解锁互斥锁
intpthread_mutex_destroy(pthread_mutex_t
在示例代码中使用互斥锁
 添加互斥锁到原生代码:
/*互斥锁*/
staticpthread_mutex_tmutex;
 在Java_cn_yue_nativethreads_MainActivity_nativeInit函数中初始化互斥锁
//初始化互斥锁
 if (0 != pthread_mutex_init(&mutex, NULL)) {
//获取异常类
jclass exceptionClazz = env->FindClass("java/lang/RuntimeException");
//抛出异常
"Unable toinitialize mutex!");
 goto exit;
 }
在Java_cn_yue_nativethreads_MainActivity_nativeFree函数中销毁互斥锁
//销毁互斥锁
 if (0 != pthread_mutex_destroy(&mutex)) {
//获取异常类
jclass exceptionClazz = env->FindClass("java/lang/RuntimeException");
//抛出异常
"Unable to destorymutex!");
 }
在Java_cn_yue_nativethreads_MainActivity_nativeWorker函数中使用互斥锁
/*
* 原生worker
* Class: cn_yue_nativethreads_MainActivity
* Method: nativeWorker
* Signature: (II)V
*/
voidJava_cn_yue_nativethreads_MainActivity_nativeWorker(JNIEnv
jobject obj,  jint id, jint
//锁定互斥锁
 if (0 != pthread_mutex_lock(&mutex)) {
//获取异常类
jclass exceptionClazz = env->FindClass("java/lang/RuntimeException");
//抛出异常
"Unable to lock mutex!");
 goto exit;
 }
//循环给定的迭代次数
 for (jint
//准备消息
 char message[26];
 sprintf(message, "worker %d: iteration %d", id, i);
//来自c字符串的消息
jstring
//调用原生消息方法
 env->CallVoidMethod(obj,gOnNativeMessage, messageString);
//检查是否发和异常
 if (NULL != env->ExceptionOccurred()) {
 break;
 }
 sleep(1);
 }
//解锁互斥锁
 if (0 != pthread_mutex_unlock(&mutex)) {
//获取异常类
jclass exceptionClazz = env->FindClass("java/lang/RuntimeException");
//抛出异常
"Unable to unlock mutex!");
 }
 exit: return;
}
运行示例程序,得到锁的线程会先执行,以此类推
B 信号量(semaphores)
使用信号量同步posix线程
添加头文件#include <semaphore.h>
初始化信号量
externintsem_init(sem_t
 int pshared,//共享标志
 unsignedint value);//初始值
锁定信号量
externintsem_wait(sem_t
解锁信号量
externintsem_post(sem_t
销毁信号量
externintsem_destroy(sem_t
6 posix线程的优先级和调度策略
最常使用的调度策略:
SCHED_FIFO:先进先出,基于线程进入列表的时间进行排序,也可以基于优先级
SCHED_RR:循环轮转,是线程执行时间加以限制的SCHED_FIFO,其目的避免线程独占可用的cpu时间
以上调度策略在sched.h头文件中定义,可以在pthread_create创建线程时,用pthread_attr_t的sched_policy域来定义调度策略
也可以在运行时调用,
intpthread_setschedparam(pthread_t
int poilcy,//调度策略
structsched_paramconst * param);//参数
posixThread的优先级
在pthread_create创建线程时,用pthread_attr_t的sched_policy域来定义调度优先级,也可以在运行时调用,intpthread_setschedparam函数参数中的param中提供优先级
Sched_get_priority_max和Sched_get_priority_min来查询优先级的最大最小值