线程私有变量

线程对象也是从一个(线程)类而构建的,线程类作为一个类也可以拥有自己的私有成员。这个成员为此线程对象私有,有时候使用线程私有变量,会巧妙避免一些并发安全的问题,提高程序的灵活性和编码的复杂度。
下面举例来说吧,统计一个线程类创建过多少个线程,并为每个线程进行编号。

/** 
* 为线程添加编号,并确所创建过线程的数目 
* 
* @author SWPU 2019-12-24 16:38:31 
*/ 
public class ThreadVarTest { 
        public static void main(String[] args) { 
                Thread t1 = new MyThread(); 
                Thread t2 = new MyThread(); 
                Thread t3 = new MyThread(); 
                Thread t4 = new MyThread(); 
                t1.start(); 
                t2.start(); 
                t3.start(); 
                t4.start(); 
        } 
} 

class MyThread extends Thread { 
        private static int sn = 0;    //线程数 
        private int x = 0;                    //线程编号 

        MyThread() { 
                x = sn++; 
        } 

        @Override 
        public void run() { 
                Thread t = Thread.currentThread(); 
                System.out.println(t.getName() + "\t" + x); 
        } 
}

运行结果

Thread-0 0
Thread-1 1
Thread-2 2
Thread-3 3

### C++ 中线程私有变量与资源管理 在 C++ 的多线程编程中,无论是使用 POSIX 线程(`pthread`)还是标准库中的 `std::thread`,都需要特别关注线程间的数据隔离以及资源共享的安全性。以下是关于如何在线程之间管理和保护数据的一些核心概念。 #### 使用 `pthread_mutex` 进行同步 当多个线程访问共享资源时,为了防止竞争条件的发生,可以使用互斥锁 (`mutex`) 来实现对这些资源的独占访问。例如,在使用 `pthread_mutex_t` 类型的锁时,可以通过以下方式完成初始化、加锁和解锁操作: ```c++ #include <pthread.h> // 定义并初始化互斥锁 pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER; void* thread_function(void* arg) { pthread_mutex_lock(&lock); // 加锁 // 访问共享资源 pthread_mutex_unlock(&lock); // 解锁 return NULL; } ``` 对于局部变量定义的锁,需显式调用 `pthread_mutex_init` 和 `pthread_mutex_destroy` 函数[^2]。而对于全局变量,则可以直接利用宏 `PTHREAD_MUTEX_INITIALIZER` 初始化,并无需手动销毁。 #### 数据隔离策略 为了避免不同线程之间的干扰,通常会采用以下几种方法来处理线程内的私有变量或资源: 1. **线程本地存储 (Thread Local Storage, TLS)** 在 C/C++ 中,TLS 是一种机制,允许为每个线程分配独立的实例副本。POSIX 提供了 `pthread_key_create()` 接口用于创建键值关联到特定线程上的数据结构。而现代 C++ 则引入了关键字 `thread_local`,简化了这一过程。 ```cpp thread_local int private_variable = 0; // 每个线程拥有自己的拷贝 ``` 2. **消息传递模式** 如果某些情况下不希望直接暴露共享状态给其他线程,而是通过队列等方式间接通信,则可考虑基于生产者-消费者模型的消息传递设计思路。此时往往配合条件变量(`condition variable`) 实现等待/通知逻辑[^1]。 3. **无锁算法** 对于性能敏感场景下频繁读取少量写入的操作对象来说,可能更适合选用原子类型或者借助硬件指令支持构建更高效的解决方案而非依赖传统锁定手段。 #### 示例代码展示 下面给出一段综合运用上述技术点的小例子——两个工作线程分别累加同一个计数器但保持各自进度记录不受影响的同时又能最终汇总结果: ```cpp #include <iostream> #include <thread> #include <atomic> #include <mutex> std::mutex mtx; // 控制打印顺序使用的互斥量 std::atomic<int> shared_counter{0}; // 原子整数代表公共统计数值 int local_sum_thread_a = 0; // 局部求和A int local_sum_thread_b = 0; // 局部求和B void worker_a(int iterations){ for(auto i=0;i<iterations;++i){ ++shared_counter.load(); // 更新全局计数器 local_sum_thread_a +=i*i; // 自己内部计算平方和 } } void worker_b(int iterations){ for(auto j=0;j<iterations;++j){ ++shared_counter.fetch_add(1,std::memory_order_relaxed); local_sum_thread_b+=j*j*j; } } int main(){ const size_t num_operations_per_worker=1e6; std::thread t1(worker_a,num_operations_per_worker),t2(worker_b,num_operations_per_worker); t1.join(); t2.join(); { // 打印部分包裹在一个作用域里方便上锁控制输出流安全 std::unique_lock<std::mutex> lck(mtx); std::cout << "Total operations performed:"<<shared_counter<<"\n"; std::cout<<"Local sum A:"<<local_sum_thread_a<<", B:"<<local_sum_thread_b<<"\n"; } return 0;} ``` 此程序展示了如何结合原子操作维护跨线程一致性的计数器,同时也保留每条执行路径独有的中间累积成果。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值