Android-Jni线程(二)— 线程锁之生产者消费者

来源:互联网 发布:java web权限管理框架 编辑:程序博客网 时间:2024/06/11 22:35

目录:

        Android-Jni线程(一)— 创建线程

        Android-Jni线程(二)— 线程锁之生产者消费者

        Android-Jni线程(三)— JNI全局回调java方法


        上一篇博客《Android-Jni线程(一)— 创建线程》我们在Jni层创建了一个最简单的线程但啥事也没有做,总感觉没什么实际的作用,现在我们就来实现经典的“生产者和消费者”线程锁模型。先看看演示效果:




首先还是老规矩先讲讲大体步骤:

1、创建生产者和消费者2个线程:pthread_t   pthread_produc,pthread_customer。

2、创建线程锁和条件对象:pthread_mutex_t mutex和pthread_cond_t cond。

3、创建产品队列queue(C++中“queue”头文件)。

5、生产者定时生产产品往队列queue添加(push)产品,并通知(pthread_cond_signal)消费者可以消费了;消费者快速从queue取出(pop)产品消费,当queue中没有产品(size == 0)时,就阻塞等待(pthread_cond_wait)生产者生产产品后的通知并马上消费。

6、生产者添加产品(queue.push)和消费者消费产品(queue.pop)时都在线程锁中(pthread_mutex_lock)执行,当添加/消费产品后就解锁线程(pthread_mutex_unlock),这样就能保证同一时刻只有生产者或消费者才能对产品进行操作。

接下来Jni中用C++代码实现:

#include <jni.h>#include "AndroidLog.h"#include "pthread.h"#include "unistd.h"#include "queue"//1、一般线程pthread_t pthread;//线程对象void *threadDoThings(void *data){    LOGD("jni thread do things");    pthread_exit(&pthread);}extern "C"JNIEXPORT void JNICALLJava_com_ywl5320_jnithread_JniThread_normalThread(JNIEnv *env, jobject instance) {    // TODO    LOGD("normal thread");    //创建线程    pthread_create(&pthread, NULL, threadDoThings, NULL);}//2、线程锁std::queue<int> queue; //产品队列,里面是int的队列pthread_t pthread_produc; //生产者线程pthread_t pthread_customer; //消费者线程pthread_mutex_t mutex; //线程锁pthread_cond_t cond; //条件对象void *ptoducThread(void *data){    while(queue.size() < 50)    {        LOGD("生产者生产一个产品");        pthread_mutex_lock(&mutex); //操作队列前先加锁        queue.push(1);        if(queue.size() > 0)        {            LOGD("生产者通知消费者有产品产生,产品数量为:%d", queue.size());            pthread_cond_signal(&cond); //有了产品通知消费者        }        pthread_mutex_unlock(&mutex); //解锁线程        sleep(4); //休息4秒,单位是秒    }    pthread_exit(&pthread_produc);}void *customerThread(void *data){    char *prod = (char *) data;    LOGD("%", prod);    while(1) //这里用死循环,时间情况应该给一个变量来控制跳出循环    {        pthread_mutex_lock(&mutex); //操作队列前先加锁        if(queue.size() > 0)        {            queue.pop();            LOGE("消费者消费一个产品,产品数量为:%d", queue.size());        } else{            LOGE("产品消费完了,等待生产者生产......");            pthread_cond_wait(&cond, &mutex); //阻塞线程等待生产者的通知        }        pthread_mutex_unlock(&mutex);//解锁线程        usleep(500 * 1000); //休息0.5秒,usleep单位是微妙    }    pthread_exit(&pthread_customer);}void initMutex(){    pthread_mutex_init(&mutex, NULL); //初始化锁对象 对应pthread_mutex_destroy销毁锁对象    pthread_cond_init(&cond, NULL); //初始化条件变量 对应pthread_cond_destroy销毁条件变量    pthread_create(&pthread_produc, NULL, ptoducThread, (void *) "product"); //创建生产者线程,并传递参数    pthread_create(&pthread_customer, NULL, customerThread, NULL); //创建消费者线程}extern "C"JNIEXPORT void JNICALLJava_com_ywl5320_jnithread_JniThread_mutexThread(JNIEnv *env, jobject instance) {    // TODO    //初始化时,先往队列中添加10个产品    for(int i = 0; i < 10; i++)    {        queue.push(i);    }    initMutex();}

根据注释和上文的步骤思路就很好理解“生产者和消费者”模型了,在ffmpeg中音视频解码时就用到了这个模型,后面也会介绍用ffmpeg解码音视频的。现在是打基础的时候 哈哈。下一篇博客将介绍:在c++中全局调用java方法达到回调效果。


源码下载:Github:Android-JniThread 欢迎star






原创粉丝点击