`
一路欢笑一路走
  • 浏览: 11644 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

ThreadLocal类实例详解

 
阅读更多

1.ThreadLocal实例

    Num类

    

class IncreaseNum {
	ThreadLocal<Integer> num = new ThreadLocal<Integer>();

	public Integer getNextNum() {
		if(num.get()==null){
			//初始化是0
			num.set(0);
		}else{
			num.set(num.get() + 1);
		}
		return num.get();
	}
}

 

 

   线程类

   

class IncreaseNumThread extends Thread {

	IncreaseNum entity;

	public IncreaseNumThread(IncreaseNum entity) {
		this.entity = entity;
	}

	@Override
	public void run() {
		for(int i=0;i<3;i++){
			System.out.println(Thread.currentThread().getName() + "的数字"+ entity.getNextNum());
		}

 

 

 

   测试类

   

public static void main(String[] args) {
		IncreaseNum entity = new IncreaseNum();
		IncreaseNumThread thread1 = new IncreaseNumThread(entity);
		IncreaseNumThread thread2 = new IncreaseNumThread(entity);
		IncreaseNumThread thread3 = new IncreaseNumThread(entity);
		thread1.start();
		thread2.start();
		thread3.start();
	}	}
}

   

 

   结果

Thread-2的数字0
Thread-2的数字1
Thread-0的数字0
Thread-1的数字0
Thread-1的数字1
Thread-1的数字2
Thread-0的数字1
Thread-0的数字2
Thread-2的数字2

    

 

    如果按照正常来说的话3个线程共享一个实例,数字应该从0-8,但是现在每个线程的数字都是从0-2.这就是ThreadLocal的作用。

 

2.ThreadLocal类介绍

    早在JDK 1.2的版本中就提供java.lang.ThreadLocal,ThreadLocal为解决多线程程序的并发问题提供了一种新的思路。使用这个工具类可以很简洁地编写出优美的多线程程序。

 

ThreadLocal很容易让人望文生义,想当然地认为是一个“本地线程”。其实,ThreadLocal并不是一个Thread,而是Thread的局部变量,也许把它命名为ThreadLocalVariable更容易让人理解一些。

 

当使用ThreadLocal维护变量时,ThreadLocal为每个使用该变量的线程提供独立的变量副本,所以每一个线程都可以独立地改变自己的副本,而不会影响其它线程所对应的副本。

 

从线程的角度看,目标变量就象是线程的本地变量,这也是类名中“Local”所要表达的意思

 

 

 API定义

 

该类提供了线程局部 (thread-local) 变量。这些变量不同于它们的普通对应物,因为访问某个变量(通过其 get 或 set 方法)的每个线程都有自己的局部变量,它独立于变量的初始化副本。ThreadLocal 实例通常是类中的 private static 字段,它们希望将状态与某一个线程(例如,用户 ID 或事务 ID)相关联。

 

主要方法get()

 

public T get() {
        Thread t = Thread.currentThread();
        ThreadLocalMap map = getMap(t);
        if (map != null) {
            ThreadLocalMap.Entry e = map.getEntry(this);
            if (e != null)
                return (T)e.value;
        }
        return setInitialValue();
 }

 可以看出get方法和当前线程有关,用map来存储,当前线程作为key,然后赋值,当取值的时候取出来的和当前线程相关,而不会影响其他线程的值。

 

 

3.ThreadLocal和线程同步比较

  1)在同步机制中,通过对象的锁机制保证同一时间只有一个线程访问变量。这时该变量是多个线程共享的,使用同步机制要求程序慎密地分析什么时候对变量进行读写,什么时候需要锁定某个对象,什么时候释放对象锁等繁杂的问题,程序设计和编写难度相对较大。

 2)ThreadLocal则从另一个角度来解决多线程的并发访问。ThreadLocal会为每一个线程提供一个独立的变量副本,从而隔离了多个线程对数据的访问冲突。因为每一个线程都拥有自己的变量副本,从而也就没有必要对该变量进行同步了。ThreadLocal提供了线程安全的共享对象,在编写多线程代码时,可以把不安全的变量封装进ThreadLocal

   概括起来说,对于多线程资源共享的问题,同步机制采用了以时间换空间的方式,而ThreadLocal采用了以空间换时间的方式。前者仅提供一份变量,让不同的线程排队访问,而后者为每一个线程都提供了一份变量,因此可以同时访问而互不影响。

 

      

 

ThreadLocal的应用场景:

 

1)Spring使用ThreadLocal解决线程安全问题

 

    我们知道在一般情况下,只有无状态的Bean才可以在多线程环境下共享,在Spring中,绝大部分Bean都可以声明为singleton作用域。就是因为Spring对一些Bean(如RequestContextHolder、TransactionSynchronizationManager、LocaleContextHolder等)中非线程安全状态采用ThreadLocal进行处理,让它们也成为线程安全的状态,因为有状态的Bean就可以在多线程中共享了

 

2)分页信息的存储

 

   每次请求都带有自己的分页信息,这些请求是并发的,为了保证每次请求的分页信息相互不影响,可以采用ThreadLocal保证线程并发的安全。

 

 

 

 

分享到:
评论

相关推荐

    Java ThreadLocal用法实例详解

    Java ThreadLocal用法实例详解 Java ThreadLocal是Java中的一种线程局部变量机制,用于保存每个线程独有的数据,以避免线程之间的数据共享问题。ThreadLocal的基本使用非常简单,只需要定义一个ThreadLocal变量,...

    java中ThreadLocal详解

    在Java多线程编程中,`ThreadLocal`是一个非常重要的工具类,它提供了一种在每个线程内部存储线程私有实例的方法。通常情况下,当多个线程共享某个变量时,可能会引发线程安全问题。而`ThreadLocal`则提供了另一种...

    Java 中ThreadLocal类详解

    当线程结束之前没有调用`remove`方法,ThreadLocal实例将无法被垃圾收集,因为它仍然在Thread的ThreadLocalMap中有一个引用。因此,需要在不再需要ThreadLocal变量时记得清理。 总之,Java中的ThreadLocal是处理...

    JAVA ThreadLocal类深入

    例如,HibernateUtil类中会定义一个ThreadLocal变量来保存SessionFactory创建的Session实例,便于在多线程环境下安全地使用。 ```java public class HibernateUtil { private static final ThreadLocal&lt;Session&gt; ...

    2、导致JVM内存泄露的ThreadLocal详解

    1. **避免共享ThreadLocal实例**:确保每个类都有自己的`ThreadLocal`实例,避免不同类之间共享`ThreadLocal`对象。 2. **谨慎使用继承**:如果`ThreadLocal`是在父类中定义的,子类可能会无意中访问到不属于当前...

    ThreadLocal详解

    例如,在Spring的DAO模板类中,尽管底层的数据连接或会话资源是非线程安全的,但是通过使用ThreadLocal,可以为每个线程绑定独立的数据连接或会话,使得多个DAO可以复用同一个模板实例而不会发生资源冲突,极大地...

    java ThreadLocal使用案例详解

    Java ThreadLocal使用案例详解 Java ThreadLocal是Java语言中的一种机制,用于为每个线程提供一个独立的变量副本,以解决多线程环境下共享变量的线程安全问题。在本文中,我们将详细介绍Java ThreadLocal的使用案例...

    Java 并发编程之ThreadLocal详解及实例

    在这个例子中,`UniqueThreadIdGenerator` 类使用 `ThreadLocal` 来为每个线程生成唯一的 ID。`initialValue()` 方法会在每个线程首次访问 `uniqueNum` 时被调用,返回一个递增的 ID。 5. **注意事项** - 虽然 `...

    java 中ThreadLocal实例分析

    "Java 中ThreadLocal实例分析" Java 中的 ThreadLocal 实例分析是指在多线程环境下,如何使用 ThreadLocal 来实现线程安全。ThreadLocal 是 Java 中的一种机制,用于在多个线程中实现变量的隔离。 在上面的代码中...

    入研究java.lang.ThreadLocal类.docx

    ### 知识点详解:Java.lang.ThreadLocal 类 #### 一、概述 **ThreadLocal** 并非线程的一种特殊实现形式,而是一种为每个线程提供独立副本的机制,通常被称为“线程局部变量”。这种机制使得每个线程都可以独立...

    ThreadLocal

    ### ThreadLocal核心概念详解 #### 一、ThreadLocal简介与重要性 ThreadLocal是一个非常重要的Java并发工具类,它的核心概念在于为每一个线程提供了一个独立的变量副本,从而避免了线程之间的数据竞争问题。这使得...

    ThreadLocal、InheritableThreadLocal详解

    因此,不同线程访问同一个ThreadLocal实例时,它们看到的是各自的副本,互不影响。 ```java ThreadLocal&lt;String&gt; thl = new ThreadLocal(); thl.set("ThreadA variable"); ``` 在上述代码中,`thl`在每个线程中都...

    实例详解Java中ThreadLocal内存泄露

    在使用`ThreadLocal`时,一定要确保在恰当的时机清除其存储的引用,以避免长期持有不必要的类加载器实例,导致内存资源浪费。在Java EE环境中,尤其需要注意这类问题,因为容器的特殊性可能导致不易察觉的内存泄漏。...

    Android 详解ThreadLocal及InheritableThreadLocal

    这意味着每个线程都拥有ThreadLocal变量的私有实例,它们之间互不干扰。在Android中,ThreadLocal常被用来存储线程相关的数据,例如Handler中的Looper对象,因为Looper与线程紧密关联,每个线程通常只有一个Looper,...

    Java资料-详解ThreadLocal

    `ThreadLocal`的工作原理是为每个线程创建一个单独的实例副本,这些副本存储在一个与线程相关的映射表中。当线程执行时,它首先查找自己的副本,如果没有,则会自动创建。 让我们通过一个简单的例子来理解`...

    8个案例详解教会你ThreadLocal.docx

    通过以上介绍,我们可以了解到 `ThreadLocal` 在处理多线程环境中提供了独特的数据隔离机制,常用于创建线程安全的工具类实例,或者在每个线程内部保存全局变量。正确使用和管理 `ThreadLocal` 是避免潜在问题的关键...

    JAVA开发常用类库UUID、Optional、ThreadLocal、TimerTask、Base64使用方法与实例详解

    主要介绍了JAVA开发常用类库UUID、Optional、ThreadLocal、TimerTask、Base64使用方法与实例详解,需要的朋友可以参考下

    java核心知识点学习----多线程间的数据共享和对象独立,ThreadLocal详解.pdf

    在上述代码中,创建了一个ThreadLocal实例,然后在线程的run()方法中设置值,每个线程设置的数据只对自己可见,不会影响其他线程。这样既实现了数据共享(所有线程可以访问到ThreadLocal),又确保了对象独立(每个...

    Synchronized与ThreadLocal

    - 每个线程都拥有自己的 ThreadLocal 实例,这些实例是相互独立的,因此不存在线程安全问题。 - **使用场景:** - 当需要为每个线程分配独立的数据时,ThreadLocal 是一个很好的选择。 - 例如,在连接池管理、...

Global site tag (gtag.js) - Google Analytics