`

Threadloca共享线程局部变量和线程同步机制的区别(转载)

 
阅读更多
Threadloca是解决线程安全问题的一个很好的思路,他通过为每个线程提供一个独立的变量副本解决解决了变量并发访问的冲突问题。在很多情况下,ThreadLocal比直接使用synchronized同步机制解决线程安全问题更简单,更方便,且结果程序拥有更高的并发性。
对于多线程资源共享的问题,同步机制采用了“以时间换空间”的方式,而ThreadLocal采用了“以空间换时间”的方式。前者仅提供一份变量,让不同的线程排队访问,而后者为每一个线程都提供了一份变量,因此可以同时访问而互不影响。
ThreadLocal 并不能替代同步机制,两者面向的问题领域不同。

1:同步机制是为了同步多个线程对相同资源的并发访问,是为了多个线程之间进行通信的有效方式;

2:而threadLocal是隔离多个线程的数据共享,从根本上就不在多个线程之间共享变量,这样当然不需要对多个线程进行同步了。
import java.util.Random;


public class ThreadSocpeShareData {
  static ThreadLocal<Integer> t = new ThreadLocal<Integer>();
     public static void main(String[] args) {
    	 for(int i=0;i<3;i++){
    		 new Thread(new Runnable() {
    				
    				@Override
    				public void run() {
    				   int  data = new Random().nextInt();
    				 
    		    		System.out.println(Thread.currentThread().getName() +" has put "+ data);
    		    		  t.set(data);
    		    		MyThreadScopeData.getInstance().setName("name" + data);
    		    		MyThreadScopeData.getInstance().setAge("age"+data);
    					new A().get();
    					new B().get();
    				}
    			}).start();
    	 }
  }
    
     static class A{
    	 public void get(){
    		 int  data = t.get();
    		 MyThreadScopeData myData = MyThreadScopeData.getInstance();
    		 System.out.println("A " + Thread.currentThread().getName() +" "+ data + myData.getAge() + myData.getName()   /*ms.getName()*/);
    	 }
     }
     static class B{
    	 public void get(){
    		 int  data = t.get();
    		 System.out.println("B " + Thread.currentThread().getName()+ " "+ data);
    	 }
     }
}

class MyThreadScopeData{
  
  private MyThreadScopeData(){}
  private static ThreadLocal<MyThreadScopeData> map = new ThreadLocal<MyThreadScopeData>();
  public static MyThreadScopeData getInstance(){
    MyThreadScopeData instance = map.get();
    if(instance == null){
      instance = new MyThreadScopeData();
      map.set(instance);
    }
    return instance;
  }
  
  
  
  private String name;
  private String age;
  public String getName() {
    return name;
  }
  public void setName(String name) {
    this.name = name;
  }
  public String getAge() {
    return age;
  }
  public void setAge(String age) {
    this.age = age;
  }
  
}

事实上,我们向ThreadLocal中set的变量不是由ThreadLocal来存储的,而是Thread线程对象自身保存。当用户调用ThreadLocal对象的set(Object o)时,该方法则通过Thread.currentThread()获取当前线程,将变量存入Thread中的一个Map内,而Map的Key就是当前的ThreadLocal实例。请看源码,这是最主要的两个函数,能看出ThreadLocal与Thread的调用关系:
public void set(T value) {  
    Thread t = Thread.currentThread();  
    ThreadLocalMap map = getMap(t);  
if (map != null)  
      map.set(this, value);  
else
      createMap(t, value);  
}  
ThreadLocalMap getMap(Thread t) {  
return t.threadLocals;  
} 
  public void set(T value) { Thread t = Thread.currentThread(); ThreadLocalMap map = getMap(t); if (map != null) map.set(this, value); else createMap(t, value); } ThreadLocalMap getMap(Thread t) { return t.threadLocals; }

具体可以看看里面的源码,不过有一点是可以证实的,就是Threadlocal中 创建的线程副本,可以不调用remove来做清理工作,因为jvm在发现线程的调佣不再使用时,会进行自动的垃圾回收操作,我以前写程序在使用Threadlocal时却是经常的进行使用完成之后的清理工作。(防止占用内存,如果创建的副本数量不是太多的话,可以让虚拟机自动来清除)
分享到:
评论

相关推荐

    多线程线程变量赋值

    当多个线程共享同一资源时,数据同步和安全问题就会变得至关重要。本话题聚焦于“多线程线程变量赋值”,讨论如何在不通过参数传递的情况下,为线程变量直接赋值。 首先,我们需要理解线程变量(Thread Local ...

    局部变量线程安全测试

    测试可能包括对局部变量的读写操作,以及涉及到同步机制如synchronized关键字,volatile修饰符,或者是使用ThreadLocal等技术来确保线程安全。 在标签中,“局部变量”、“线程”、“安全”、“测试”和“源码”是...

    操作系统实验 线程同步机制

    操作系统实验 线程同步...这些同步机制可以保护共享资源免受多个线程的访问,避免了数据不一致和系统崩溃的问题。同时,这些同步机制也可以用于实现各种线程安全的数据结构和算法,提高了操作系统的稳定性和安全性。

    创建线程,利用互斥实现线程共享变量通信

    一、题目: 创建线程,利用互斥实现线程共享变量通信 二、目的 掌握线程创建和终止,加深对线程和进程概念的理解,会用同步与互斥方法实现线程之间的通信。 三、内容和要求 软件界面上点“创建线程” 按钮,创建三个...

    CVI 线程锁、线程安全变量实例

    4. **同步与通信**:可能还包括使用`cvEventWait()` 和 `cvSetEvent()` 进行线程间的同步和通信。 理解并熟练运用这些概念和技术,可以帮助你在LabWindows/CVI环境中编写出高效且稳定的多线程应用程序,避免因数据...

    C语言多线程编程:线程控制与同步机制详解

    接着,深入探讨了线程同步机制,如互斥锁、条件变量、读写锁和自旋锁的工作原理及具体应用示例。此外,还介绍了线程优先级、调度策略、线程局部存储和信号量等相关概念和技术。最后,通过生产者消费者问题和读者写者...

    14.线程的同步机制-synchronized同步方法-局部变量为线程安全.mp4

    在学习Java过程中,自己收集了很多的Java的学习资料,分享给大家,有需要的欢迎下载,希望对大家有用,一起学习,一起进步。

    共享线程和局部存储技术

    总结来说,共享内存和线程局部存储都是解决多进程或多线程环境下数据共享和隔离问题的手段。共享内存提供了高效的进程间通信途径,而线程局部存储则确保了线程间数据的安全性和独立性。了解并合理使用这两种技术,...

    Java多线程-线程的安全问题与线程的同步机制介绍

    下面我们来具体介绍线程安全问题和线程的同步机制。 一、线程安全问题 (1)介绍 当我们使用多个线程访问同一资源(可以是同一个变量、同一个文件、同一条记录等)的时候,若多个线程只有读操作,那么不会发生...

    线程局部存储机制总结

    ### 线程局部存储(TLS)机制与MFC中的实现 #### 一、线程局部存储机制概述 线程局部存储(Thread Local Storage,简称TLS)是一种编程技术,允许程序为每个线程分配独立的内存空间。这些空间只对该线程可见,其他...

    Qt 多线程访问同一个变量

    在Qt框架中,多线程编程是常见的需求,特别是在处理密集型计算或异步操作时。...在实际项目中,根据具体需求,可能还需要结合其他同步原语,如信号和槽、条件变量等,来实现更复杂的线程同步和通信。

    线程间同步机制 读写锁通信机制 线程与信号

    在Linux高级程序设计中,主要介绍了三种线程同步机制:互斥锁、条件变量和读写锁,以及线程与信号的交互。 1. **互斥锁通信机制**: 互斥锁是用于保护临界区的一种机制,确保同一时间只有一个线程能访问共享资源。...

    C#多线程互斥实例 多线程获取同一变量

    在这个"多线程互斥实例 多线程获取同一变量"的示例中,我们将探讨如何在多个线程中安全地访问共享资源,避免数据不一致性和竞态条件。 首先,我们需要理解多线程中的一些核心概念: 1. **线程**:线程是操作系统...

    qt线程共享数据 信号和槽方式

    即使用一个两个线程都能够共享的变量(如全局变量),这样两个线程都能够访问和修改该变量,从而达到共享数据的目的。 Qt 线程间共享数据是本文介绍的内容,多的不说,先来啃内容。Qt线程间共享数据主要有两种方式...

    Java分布式应用学习笔记03JVM对线程的资源同步和交互机制

    ### Java分布式应用学习笔记03:JVM对线程的资源同步和交互机制 在深入探讨Java虚拟机(JVM)如何处理线程间的资源同步与交互机制之前,我们先来明确几个关键概念:线程、多线程、同步、并发以及它们在Java中的实现...

    多线程不同步读写共享资源代码

    多线程不同步读写共享资源 文章配套代码 我在很早的时候就听说多线程不同步是可以读写共享资源的。这听起来感觉挺好,因为一旦同步线程,将在同步线程上花去一定的CPU时间片. 这一切都是真的,但是,不同步线程的...

    操作系统线程同步机制

    操作系统中的线程同步机制是确保多个线程在访问共享资源时能够有序进行,避免数据竞争和混乱的关键技术。本实验通过模拟银行账户转账操作来演示线程同步的重要性,并使用不同的同步机制进行对比。 实验目的旨在让...

Global site tag (gtag.js) - Google Analytics