Android NDK使用之--用pthread实现多线程

Android系统本身包括Java和Linux内核;因此在Android应用中实现多线程就可以是基于Java上的和基于Linux上的;今天本文介绍的就是Android利用Linux下的pthread来实现多线程;大概思路如下:
我们将异步任务需要实现的方法在Java中定义,但是运行异步任务的线程交给pthread实现;
因此首先设计一个接口,作为异步任务的业务接口:

//异步任务业务接口
public interface LocalRunnable {
    public void run();
}

定义本地方法


/**
 * 
 * @author 徐晔 线程池
 */
public class ThreadPool {
    static {
        System.loadLibrary("threadpool");
    }
    /** 初始化本地线程池 */
    public native void init();
    /** 本地线程中执行任务 */
    public native int run(LocalRunnable runnable);
    /**释放资源*/
    public native void recycle();
}

通过本地方法类生成的.h文件如下:

     com_localThread_ThreadPool.h
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
//实现pthread需要包括的接口
#include <unistd.h>
#include <pthread.h>
/* Header for class com_localThread_ThreadPool */

#ifndef _Included_com_localThread_ThreadPool
#define _Included_com_localThread_ThreadPool
#ifdef __cplusplus
extern "C" {
#endif
/*
 * Class:     com_localThread_ThreadPool
 * Method:    init
 * Signature: ()V
 */
JNIEXPORT void JNICALL Java_com_localThread_ThreadPool_init(JNIEnv *, jobject);

/*
 * Class:     com_localThread_ThreadPool
 * Method:    run
 * Signature: (Lcom/localThread/LocalRunnable;)I
 */
JNIEXPORT jint JNICALL Java_com_localThread_ThreadPool_run(JNIEnv *, jobject,
        jobject);

/*
 * Class:     com_localThread_ThreadPool
 * Method:    recycle
 * Signature: ()V
 */
JNIEXPORT void JNICALL Java_com_localThread_ThreadPool_recycle(JNIEnv *,
        jobject);

#ifdef __cplusplus
}
#endif
#endif

具体的实现代码如下:

/* DO NOT EDIT THIS FILE - it is machine generated */
#include "com_localThread_ThreadPool.h"
/* Header for class com_localThread_ThreadPool */

static JavaVM *jvm = NULL;
static jobject jobj = NULL;
static jmethodID mid = NULL;
static int flag = -1;
static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
static pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
//在加载库时执行
jint JNI_OnLoad(JavaVM *vm, void *reserved) {
    jvm = vm;
    return JNI_VERSION_1_6;
}
//在卸载库时执行
void JNI_OnUnLoad(JavaVM *vm, void *reserved) {
    jvm = NULL;
}
//pthread中执行的函数
void *nativeWork(void *args) {
    JNIEnv *env = NULL;
    //将本地线程连接到虚拟机上,这样本地线程才对虚拟机可见并且可以访问到虚拟机所在进程的资源
    if (0 == jvm->AttachCurrentThread(&env, NULL)) {
        while (flag == 0) {
            if (jobj == NULL) {
            //进入等待
                pthread_cond_wait(&cond, &mutex);
            } else {
            //执行方法
                env->CallVoidMethod(jobj, mid);
                env->DeleteGlobalRef(jobj);
                jobj = NULL;
            }
        }
        jvm->DetachCurrentThread();
    }
    return (void *) 1;
}

/*
 * Class:     com_localThread_ThreadPool
 * Method:    init
 * Signature: ()V
 */
JNIEXPORT void JNICALL Java_com_localThread_ThreadPool_init(JNIEnv * env,
        jobject obj) {
    if (NULL == mid) {
    //缓存方法
        jclass cls = env->FindClass("com/localThread/LocalRunnable");
        mid = env->GetMethodID(cls, "run", "()V");
        if (mid == NULL) {
            return;
        }
        flag = 0;
        pthread_t thread;
        //创建新线程
        pthread_create(&thread, NULL, nativeWork, NULL);
    }
}

/*
 * Class:     com_localThread_ThreadPool
 * Method:    run
 * Signature: (Lcom/localThread/LocalRunnable;)I
 */
JNIEXPORT jint JNICALL Java_com_localThread_ThreadPool_run(JNIEnv * env,
        jobject obj, jobject callback) {
        //设置参数,唤醒等待的线程
    flag=0;
    jobj = env->NewGlobalRef(callback);
    return pthread_cond_signal(&cond);
}

/*
 * Class:     com_localThread_ThreadPool
 * Method:    recycle
 * Signature: ()V
 */
JNIEXPORT void JNICALL Java_com_localThread_ThreadPool_recycle(JNIEnv * env,
        jobject obj) {
        //释放资源
    flag = -1;
    env->DeleteGlobalRef(jobj);
}

Java层对本地线程类的一个封装:


public class ThreadPoolRun {

    /** 利用阻塞队列保存任务 */
    private static LinkedBlockingDeque<BaseLocalRunnable> runnables = new LinkedBlockingDeque<BaseLocalRunnable>();
    private BaseLocalRunnable lr = null;
    public static ThreadPoolRun instance = new ThreadPoolRun();
    private ThreadPool pool = null;
    boolean runflag = false;

    private ThreadPoolRun() {
        pool = new ThreadPool();
        pool.init();
    }

    /** 添加任务 */
    public void addTask(BaseLocalRunnable runnable) {
        runnables.addLast(runnable);
    }

    /** 取出任务 */
    private BaseLocalRunnable getTask() {
        try {
            return runnables.removeFirst();
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    public void runTask() {
        synchronized (pool) {
            lr = getTask();
            if (lr != null && !runflag) {
                runflag = true;
                lr.before(lr.taskid);
                pool.run(lr);
            }
        }

    }
    //当每次执行完成上一个任务后,设置标示,运行下一个任务
    public void runend() {
        runflag = false;
        runTask();
    }
}

实现基本任务类:


public abstract class BaseLocalRunnable implements LocalRunnable, MainRunnable {

    private Handler mainHandler;
    private MainRunnable mainRunnable;
    int taskid;

    public BaseLocalRunnable(Handler mainHandler, MainRunnable mainRunnable) {
        this.mainHandler = mainHandler;
        this.mainRunnable = mainRunnable;
    }

    @Override
    public final void run() {
        onfinished(dobackground(), taskid);
    }

    public final void execute(int taskid) {
        ThreadPoolRun.instance.addTask(this);
        this.taskid = taskid;
        if (!ThreadPoolRun.instance.runflag) {
            ThreadPoolRun.instance.runTask();
        }

    }

    public abstract Object dobackground();

    @Override
    public final void onfinished(final Object object, final int raskid) {
        mainHandler.post(new Runnable() {
            @Override
            public void run() {
                if (mainRunnable != null) {
                    mainRunnable.onfinished(object, raskid);
                }
                // 读取下一个信息
                ThreadPoolRun.instance.runend();
            }
        });

    }

    @Override
    public final void before(int id) {
        if (mainRunnable != null) {
            mainRunnable.before(id);
        }
    }

}

主类需要实现的接口:


public interface MainRunnable {

    public void before(int id);

    public void onfinished(Object object, int raskid);

}

测试代码:


public class Task extends BaseLocalRunnable {

    public Task(Handler mainHandler, MainRunnable mainRunnable) {
        super(mainHandler, mainRunnable);
    }

    @Override
    public Object dobackground() {
        try {
            Thread.sleep(3000);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return "执行完成";
    }

}


public class TestActivity extends Activity implements MainRunnable {

    private TextView text;
    private Button am_button;
    private Handler mainHandler = null;
    private Task task;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mainHandler = new Handler(getMainLooper());
        text = (TextView) findViewById(R.id.text);
        am_button = (Button) findViewById(R.id.am_button);
        am_button.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                task = new Task(mainHandler, TestActivity.this);
                task.execute(0);
            }
        });

    }

    @Override
    public void before(int id) {
        Log.v("任务", id + "开启");
    }

    @Override
    public void onfinished(Object object, int taskid) {
        Log.v("结果", "结束" + object.toString());
    }
}

运行结果如下:我连续点击了几次按钮,出现的结果是一次一次执行
这里写图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值