知识大全 Java多线程开发之线程局部变量的使用
Posted 变量
篇首语:人无常识,百事难成。本文由小常识网(cha138.com)小编为大家整理,主要介绍了知识大全 Java多线程开发之线程局部变量的使用相关的知识,希望对你有一定的参考价值。
Java多线程开发之线程局部变量的使用 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!
一 概述 现在多核时代多线程开发越来越重要了 多线程相比于多进程有诸多优势(当然也有诸多劣势) 在早期C的库中 有许多函数是线程不安全的 因为内部用到了静态变量 比如 char *strtok(char *s const char *delim) 该函数内部就有一个静态指针 如果多个线程同时调用此函数时 可能就会出现奇怪的结果 当然也不是我们所想要的 现在LINUX对此函数功能有一个线程安全版本的接口 char *strtok_r(char *s const char *delim char **ptrptr) 这就避免了多个线程同时访问的冲突问题 其实 如果保持 strtok()/ 接口不变 同时还要保证线程安全 还有一个解决办法 那就是采用线程局部变量 使用线程局部变量有两种使用方式 一个稍微麻烦些 一个比较简单 下面一一做个介绍(以LINUX为例) 二 线程局部变量的使用 比较麻烦些的使用方法用到的函数主要有三个 pthread_once(pthread_once_t* void (*init_routine)(void)) pthread_key_create()/ pthread_setspecific()/ pthread_getspecific()/ 其中 pthread_once 可以保证在整个进程空间init_routine函数仅被调用一次(它解决了多线程环境中使得互斥量和初始化代码都仅被初始化一次的问题) pthread_key_create 的参数之一指一个析构函数指针 当某个线程终止时该析构函数将被调用 并用对于一个进程内的给定键 该函数只能被调用一次 pthread_sespecific 和 pthread_getspecific 用来存放和获取与一个键关联的值 例子如下 pthread_key_t key; pthread_once_t once = PTHREAD_ONCE_INIT; static void destructor(void *ptr) free(ptr) void init_once(void) pthread_key_create(&key destructor) static void *get_buf(void) pthread_once(&once init_once) if ((ptr = pthread_getspecific(key)) == NULL) ptr = malloc( ) pthread_setspecific(key ptr) return (ptr) static void *thread_fn(void *arg) char *ptr = (char*) get_buf() sprintf(ptr hello world ) printf( 》%s\\n ptr) return (NULL) void test(void) int i n = ; pthread_t tids[ ]; for (i = ; i < n; i++) pthread_create(&tids[i] NULL thread_fn NULL) for (i = ; i < n; i++) pthread_join(&tids[i] NULL) 另外 还有一个更加简单使用线程局部变量的方法 __thread 修饰符 (在WIN 平台下需要用 __declspec(thread) 修饰符 WIN 的东东总得要多写几笔 呵呵) 于是上述代码可以修改如下 static void *get_buf(void) static __thread void *ptr = malloc( ) return (ptr) static void *thread_fn(void *arg) char *ptr = (char*) get_buf() sprintf(ptr hello world ) printf( 》%s\\n ptr) return (NULL) void test(void) int i n = ; pthread_t tids[ ]; for (i = ; i < n; i++) pthread_create(&tids[i] NULL thread_fn NULL) for (i = ; i < n; i++) pthread_join(&tids[i] NULL) 看到没有 这段代码比前面一个简单许多 但却有一个问题 它存在内存泄露问题 因为当线程退出时各个线程分配的动态内存(ptr = malloc( )) 并没有被释放 三 用ACL线程接口操作线程局部变量 为了解决上述问题 ACL库中实现了线程局部变量的简单释放功能 acl_pthread_atexit_add(void *arg void (*free_callback)(void*)) 修改上述代码如下 static void free_fn(void *ptr) free(ptr) static void *get_buf(void) static __thread void *ptr = malloc( ) acl_pthread_atexit_add(ptr free_fn) return (ptr) static void *thread_fn(void *arg) char *ptr = (char*) get_buf() sprintf(ptr hello world ) printf( 》%s\\n ptr) return (NULL) void test(void) int i n = ; pthread_t tids[ ]; for (i = ; i < n; i++) acl_pthread_create(&tids[i] NULL thread_fn NULL) for (i = ; i < n; i++) acl_pthread_join(&tids[i] NULL) ok 一切问题得到解决 细心的读者会发现 pthread_create pthread_join 前面都加了前缀 acl_ 这是因为 ACL库对线程库进行了封装 以适应不同平台下(UNIX WIN )下的使用 这个例子是跨平台的 WIN 下同样可用 cha138/Article/program/Java/gj/201311/27360相关参考
Java多线程编程基础之线程和多线程 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧! 随着计算机技
Java多线程编程基础之线程对象 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧! &nbs
Java开发中多线程同步技巧[3] 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧! &nb
Java开发中多线程同步技巧[2] 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧! &nb
Java开发中多线程同步技巧[1] 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧! &nb
知识大全 Java 理论与实践: 正确使用 volatile 变量 线程同步
Java理论与实践:正确使用volatile变量线程同步 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下
实战Java多线程编程精要之高级支持 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧! 线程组 线
知识大全 Java多线程之ConcurrentHashMap深入分析
Java多线程之ConcurrentHashMap深入分析 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一
Java多线程之volatile深入分析 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧! vola
实战Java多线程编程精要之限制优先级 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧! 限制线程优