暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

二、线程池是如何实现的

重塑之路 2020-05-21
331

本节是系列课程《利用JNI实现线程池》的第二节,本节将分享如何实现线程池


完整课程获取方式:关注启明南后回复:jni线程池


文章中贴出的是核心代码,完整代码获取方式:关注本公众号后回复:jni线程池源码


学习本章节需要什么基础


1、第一章节需要的所有基础

2、对Java的线程池有一定的了解

3、对Linux下的互斥锁、条件变量有一定的了解


线程池理论知识


一个完整的线程池是由线程池、任务池两部分组成


线程池的功能包含:

1、线程池初始化,并启动最小线程数成功运行

2、线程池的资源回收

3、线程池的扩容与释放空闲线程

4、关闭线程池


本章节完成线程的前两个功能



Java端代码


1、线程池类代码

package com.qimingnan.jni.threadpool.mythreadpool;


public class MyThreadPool {


public native void init(int minSize, int maxSize);


public native void destroy();


}


2、main函数所在类代码

package com.qimingnan.jni.threadpool.mythreadpool;


public class ThreadPoolApplication {


public static MyThreadPool threadPool;


public static void main(String[] args) {
System.loadLibrary("hello");


threadPool = new MyThreadPool();


threadPool.init(2, 5);


threadPool.destroy();
}
}


JNI端核心代码


1、线程池结构

typedef struct thread_pool_t {
/* 互斥锁,用于在多线程环境下操作本结构体保证同步性 */
pthread_mutex_t lock;


/* 所有工作线程的ID的集合 */
pthread_t* worker_tids;


/* 线程池的最小线程数 */
jint thr_min_size;


/* 线程池的最大线程数 */
jint thr_max_size;


/* 线程池的存活线程数 */
jint thr_live_size;


/* 线程池的繁忙线程数 */
jint thr_busy_size;
}thread_pool, *pthread_pool;


2、init方法

JNIEXPORT void JNICALL Java_com_qimingnan_jni_threadpool_mythreadpool_MyThreadPool_init
(JNIEnv *jEnv, jobject jobj, jint minSize, jint maxSize) {
if (0 != thread_pool_init(jEnv, minSize, maxSize)) {
throwRuntimeException(jEnv, "初始化线程池失败");


return;
}
}


3、线程池初始化方法

jint thread_pool_init(JNIEnv *jEnv, jint minSize, jint maxSize) {
/* 为线程池申请内存 */
g_pthread_pool = calloc(1, sizeof(thread_pool));
if (NULL == g_pthread_pool) {
throwRuntimeException(jEnv, "为线程池分配内存失败");


goto return1;
}


/* 为工作线程集合分配内存 */
g_pthread_pool->worker_tids = calloc(maxSize, sizeof(pthread_t));
if (NULL == g_pthread_pool->worker_tids) {
throwRuntimeException(jEnv, "为工作线程集合分配内存失败");


goto return2;
}


/* 初始化互斥锁 */
if (0 != pthread_mutex_init(&g_pthread_pool->lock, NULL)) {
throwRuntimeException(jEnv, "初始化互斥锁失败");


goto return3;
}


g_pthread_pool->thr_min_size = minSize;
g_pthread_pool->thr_max_size = maxSize;
g_pthread_pool->thr_live_size = minSize;
g_pthread_pool->thr_busy_size = 0;


/* 启动最小工作线程 */
for (int i = 0; i < g_pthread_pool->thr_live_size; ++i) {
pthread_create(&g_pthread_pool->worker_tids[i], NULL, worker_thread_fn, NULL);
}


return 0;


return3:
free(g_pthread_pool->worker_tids);
g_pthread_pool->worker_tids = NULL;
return2:
free(g_pthread_pool);
g_pthread_pool = NULL;
return1:
return -1;
}


编译运行


1、编译(MAC端

jcc -dynamiclib -I /Library/Java/JavaVirtualMachines/openjdk-12.0.2.jdk/Contents/Home/include/
com_qimingnan_jni_threadpool_MyThread.c common.c
-o libhello.jnilib


2、运行结果

我是工作线程
我是工作线程
【线程池销毁程序】任务执行结束,开始释放资源


各位童鞋在阅读源码或实践的过程中有任何疑惑可留言,我会抽时间一一回复

文章转载自重塑之路,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论