`
wankunde
  • 浏览: 162868 次
  • 性别: Icon_minigender_1
  • 来自: 南京
社区版块
存档分类
最新评论

ThreadLocal - 多线程共享变量的独立拷贝

 
阅读更多

基本概念

  为每一个使用该变量的线程都提供一个变量值的副本,是每一个线程都可以独立地改变自己的副本,而不会和其它线程的副本冲突。从线程的角度看,就好像每一个线程都完全拥有该变量。使用场景

  To keep state with a thread (user-id, transaction-id, logging-id) To cache objects which you need frequently

ThreadLocal类

  它主要由四个方法组成initialValue(),get(),set(T),remove(),其中值得注意的是initialValue(),该方法是一个protected的方法,显然是为了子类重写而特意实现的。该方法返回当前线程在该线程局部变量的初始值,这个方法是一个延迟调用方法,在一个线程第1次调用get()或者set(Object)时才执行,并且仅执行1次。ThreadLocal中的确实实现直接返回一个null:

 

 

package com.baobaotao.basic;

public class SequenceNumber {
	// ①通过匿名内部类覆盖ThreadLocal的initialValue()方法,指定初始值
	private static ThreadLocal seqNum = new ThreadLocal() {
		public Integer initialValue() {
			return 0;
		}
	};
	// ②获取下一个序列值
	public int getNextNum() {
		seqNum.set((Integer) seqNum.get() + 1);
		return (Integer) seqNum.get();
	}
	public static void main(String[] args) {
		SequenceNumber sn = new SequenceNumber();
		// ③ 3个线程共享sn,各自产生序列号
		TestClient t1 = new TestClient(sn);
		TestClient t2 = new TestClient(sn);
		TestClient t3 = new TestClient(sn);
		t1.start();
		t2.start();
		t3.start();
	}
	private static class TestClient extends Thread {
		private SequenceNumber sn;
		public TestClient(SequenceNumber sn) {
			this.sn = sn;
		}
		public void run() {
			for (int i = 0; i < 3; i++) {
				// ④每个线程打出3个序列值
				System.out.println("thread[" + Thread.currentThread().getName() + "] sn[" + sn.getNextNum() + "]");
			}
		}
	}
}
/*
 * 主类中有seqNum变量,现在创建几个线程来操作该变量,其实每个线程操作的是该变量的副本
 * ThreadLocal使用方法,创建一个新对象,重写initValue方法来操作具体的值
 */
 

ThreadLocal是解决线程安全问题一个很好的思路,它通过为每个线程提供一个独立的变量副本解决了变量并发访问的冲突问题。在很多情况下,ThreadLocal比直接使用synchronized同步机制解决线程安全问题更简单,更方便,且结果程序拥有更高的并发性。

分享到:
评论

相关推荐

    彻底理解ThreadLocal 1

    ThreadLocal是Java中用于线程局部变量的一个工具类,它允许在多线程环境下为每个线程创建独立的变量副本,从而避免了线程之间的数据共享和由此引发的并发问题。ThreadLocal不是一种线程同步机制,而是提供了一种线程...

    Java源码解析ThreadLocal及使用场景

    ThreadLocal是一个非常重要的类,在多线程环境下,它可以提供线程本地变量,解决多线程间共享变量的问题,提高程序的稳定性和可靠性。 ThreadLocal的使用场景非常广泛,例如: 1. 电商系统中,用一个Long型变量...

    threadlocalpool:演示池环境中的线程局部变量

    线程局部变量(ThreadLocal)是Java编程语言中一个非常重要的特性,主要用于在多线程环境中为每个线程提供独立的变量副本。标题"threadlocalpool:演示池环境中的线程局部变量"暗示我们将探讨如何在池化的线程环境中...

    Java Concurrency的一些资料

    它的设计目标是为每个线程提供独立的变量副本,从而在多线程环境下避免了共享状态带来的同步问题。简单来说,`ThreadLocal`就像是一个线程内部的私有变量,每个线程都有一份自己的拷贝,互不影响。 **`ThreadLocal`...

    深入研究Servlet线程安全性问题

    3. **使用ThreadLocal**:ThreadLocal变量为每个线程提供独立的副本,避免了线程间的共享。 4. **避免共享状态**:设计无状态的Servlet,即不包含可变的实例变量,可以大大提高并发性能,因为无需担心线程安全。 5...

    MS知识点总结.txt

    根据提供的文件信息,我们可以整理出一系列关于Java的重要知识点,这些知识点涵盖了Java基础知识、容器管理、多线程处理、反射机制、对象拷贝以及Java Web开发等几个方面。 ### Java基础知识 1. **JDK和JRE的区别*...

    Java面试常见问题总结(2024最新版)

    - 线程共享进程资源,而进程之间是独立的。 2. **线程死锁的原因及避免方法:** - 死锁发生在多个线程相互等待对方持有的资源时。 - 避免方法包括使用有序的锁获取策略,避免嵌套锁等。 3. **sleep()方法和wait...

    Java常用并发设计模式精讲

    此外,可以使用"线程局部变量"(ThreadLocal)来为每个线程提供独立的副本,避免了线程之间的数据冲突。另外,"复制"技术,如深拷贝和浅拷贝,也能帮助减少共享状态。 3. **多线程版本的if模式**:这种模式可能指的是...

    跳槽涨薪精选面试题.pdf

    - `volatile`关键字用于确保共享变量的可见性和禁止指令重排序,适用于单个变量,但不能保证原子性。 - **ReentrantLock中的公平锁和非公平锁的底层实现** - 公平锁按照线程请求锁的顺序进行分配,而非公平锁可能...

    Java面试题和答案.pdf

    - **多线程安全**: 被`final`修饰的变量在线程间可见且不可更改,因此在多线程环境中使用`final`变量是线程安全的。 **5. `java.lang.Math.round(-1.5)`等于多少?** - `Math.round()`会将参数四舍五入到最接近的...

    2022中高级Android程序员面试必备宝典.pdf,这是一份不错的文件

    **Java多线程** - **线程创建**:掌握多种创建线程的方法。 - **线程状态**:理解线程的运行状态。 - **同步机制**:使用synchronized和volatile关键字保证线程安全。 - **线程安全**:使用ThreadLocal、锁机制等...

    (2024)跳槽涨薪必备精选面试题.pdf

    - 用于确保共享变量在多线程环境下的正确性。 3. **ReentrantLock中的公平锁和非公平锁的底层实现** - 公平锁按照请求锁的顺序授予锁,实现公平性。 - 非公平锁可能会导致饥饿现象,但在实际应用中通常具有更高...

    34234234234

    - **线程安全(Thread Safety)**: 在多线程环境中,值类型的并发访问也可能引发问题,特别是当它们作为类成员或共享变量时。线程安全的实现可能包括锁定(lock关键字)、使用volatile修饰符、线程局部存储...

    Java 20 新功能介绍.pdf

    Scoped Value 解决了在线程之间共享变量的问题,ThreadLocal 和 InheritableThreadLocal 都有其缺陷。ThreadLocal 需要手动清理,且变量不能被子线程继承;InheritableThreadLocal 可以共享信息,但是数据会拷贝多份...

    Java 最常见的面试题(208道).pdf

    Java作为一门广泛使用的编程语言,其面试题涵盖了众多的知识领域,包括基础概念、容器、多线程、反射、对象拷贝、Java Web、异常处理、网络编程、设计模式以及框架等。以下是一些核心知识点的详细说明: 1. **JDK ...

    Java线程安全问题小结_动力节点Java学院整理

    1. 可见性:Java内存模型确保了当一个线程修改了共享变量后,其他线程能看到这个修改。线程有自己的工作内存,包含从主内存中拷贝的变量副本。线程修改副本后,需要将更新后的值刷新回主内存,其他线程在下次访问时...

    Java语言的26个细节

    23. **线程局部变量**:ThreadLocal类允许每个线程拥有独立的变量副本,避免线程间数据污染。 24. **异常链**:用于保存异常处理过程中产生的多个异常信息。 25. **默认方法**:在接口中定义,Java 8引入,允许...

    java超有用的面试题目

    - **ThreadLocal原理**:每个线程拥有独立的副本,避免了线程间的共享和竞争。 - **Synchronized与Lock**:`Synchronized`关键字提供内置锁,而`Lock`接口提供更灵活的锁定机制。 - **ConcurrentHashMap**:在JDK 8...

    跳槽涨薪涨薪必备精选面试题.pdf

    14. JVM中的线程共享区包括堆内存和方法区,GC Roots包括全局静态变量、JNI引用、系统运行时数据区等。 15. 类加载器的双亲委派模型:自定义类加载器先委托给父加载器,直至Bootstrap ClassLoader,找不到再由...

    资深程序员的Java面试题总结汇总.pdf

    27. ThreadLocal为每个线程提供独立的变量副本,避免了线程间共享导致的并发问题。 28. ThreadLocal可能导致内存泄漏,因为线程结束后,ThreadLocalMap不会自动清除,需手动设置为null。 四、反射 1. 反射允许程序...

Global site tag (gtag.js) - Google Analytics