一、概述
ThreadLocal是什么呢?其实ThreadLocal并非是一个线程的本地实现版本,它并不是一个Thread,而是threadlocalvariable(线程局部变量)。也许把它命名为ThreadLocalVar更加合适。线程局部变量(ThreadLocal)其实的功用非常简单,就是为每一个使用该变量的线程都提供一个变量值的副本,是Java中一种较为特殊的线程绑定机制,是每一个线程都可以独立地改变自己的副本,而不会和其它线程的副本冲突。
从线程的角度看,每个线程都保持一个对其线程局部变量副本的隐式引用,只要线程是活动的并且 ThreadLocal 实例是可访问的;在线程消失之后,其线程局部实例的所有副本都会被垃圾回收(除非存在对这些副本的其他引用)。
通过ThreadLocal存取的数据,总是与当前线程相关,也就是说,JVM 为每个运行的线程,绑定了私有的本地实例存取空间,从而为多线程环境常出现的并发访问问题提供了一种隔离机制。
ThreadLocal是如何做到为每一个线程维护变量的副本的呢?其实实现的思路很简单,在ThreadLocal类中有一个Map,用于存储每一个线程的变量的副本。
概括起来说,对于多线程资源共享的问题,同步机制采用了“以时间换空间”的方式,而ThreadLocal采用了“以空间换时间”的方式。前者仅提供一份变量,让不同的线程排队访问,而后者为每一个线程都提供了一份变量,因此可以同时访问而互不影响。
二、API说明
ThreadLocal()
创建一个线程本地变量。
T get()
返回此线程局部变量的当前线程副本中的值,如果这是线程第一次调用该方法,则创建并初始化此副本。
protected T initialValue()
返回此线程局部变量的当前线程的初始值。最多在每次访问线程来获得每个线程局部变量时调用此方法一次,即线程第一次使用 get() 方法访问变量的时候。如果线程先于 get 方法调用 set(T) 方法,则不会在线程中再调用 initialValue 方法。
若该实现只返回 null;如果程序员希望将线程局部变量初始化为 null 以外的某个值,则必须为 ThreadLocal 创建子类,并重写此方法。通常,将使用匿名内部类。initialValue 的典型实现将调用一个适当的构造方法,并返回新构造的对象。
void remove()
移除此线程局部变量的值。这可能有助于减少线程局部变量的存储需求。如果再次访问此线程局部变量,那么在默认情况下它将拥有其 initialValue。
void set(T value)
将此线程局部变量的当前线程副本中的值设置为指定值。许多应用程序不需要这项功能,它们只依赖于 initialValue() 方法来设置线程局部变量的值。
在程序中一般都重写initialValue方法,以给定一个特定的初始值。
三、典型实例
1、创建一个Bean,通过不同的线程对象设置Bean属性,保证各个线程Bean对象的独立性。
import java.util.Random; /** * ThreadLocal类实现了线程内部的数据共享,ThreadLocal本身并不是线程,属于线程本地变量 * * 在多线程并发的情况每个线程有自己独立的本地变量空间,保护了数据安全 * * 下面的例子展示了 t1 t2 并发执行,并各自设置student对象的Age值 * * @author 吖大哥 * @date May 22, 2014 2:26:17 PM */ public class ThreadLocalTest implements Runnable { private final static ThreadLocal thLocal = new ThreadLocal(); public static void main(String[] args) { ThreadLocalTest tt = new ThreadLocalTest(); Thread t1 = new Thread(tt, "A"); Thread t2 = new Thread(tt, "B"); // 启动两个线程 t1.start(); t2.start(); } @Override public void run() { createStu(); } public void createStu() { try { System.out.println(Thread.currentThread().getName() + " 正在运行……………………"); Random r = new Random(); // 来个千年老妖 int age = r.nextInt(1000); System.out.println(Thread.currentThread().getName() + "…………设置Age的值…………" + age); Student stu = getInstance(); stu.setAge(age); System.out.println(Thread.currentThread().getName() + "…………第一次获取Age的值…………" + stu.getAge()); Thread.sleep(1000);// 暂停一会儿 System.out.println(Thread.currentThread().getName() + "…………第二次获取Age的值…………" + stu.getAge()); } catch (Exception e) { e.printStackTrace(); } } // 相当于单例 public Student getInstance() { Student stu = (Student) thLocal.get(); if (stu == null) { // 创建一个视图等对象并存储到本地线程变量中 stu = new Student(); thLocal.set(stu); } return stu; } } class Student { private int age = 0; public int getAge() { return age; } public void setAge(int age) { this.age = age; } }
相关推荐
本学习笔记将深入探讨Java多线程的相关知识,包括其原理、实现方式、同步机制以及常见问题。 ### 一、多线程的基本概念 多线程是指在一个程序中存在两个或更多的执行线程,这些线程共享同一内存空间,但各自拥有...
### 张孝祥Java多线程与并发库高级应用笔记概览 #### 一、Java多线程技术的重要性与挑战 Java线程技术是软件工程领域不可或缺的一部分,尤其在底层编程、Android应用开发以及游戏开发中,其重要性不言而喻。然而,...
在本文中,我们将深入探讨Java多线程的相关知识点,并结合提供的源代码进行学习。 1. **线程的创建** - **实现Runnable接口**:创建一个类实现Runnable接口,然后将其实例传递给Thread类的构造函数,如`Thread t =...
Java线程学习笔记涉及了Java多线程编程的多个关键知识点,本篇知识点整理将详细解释每个概念及其在Java中的实现方式。 基本知识部分包含了Java线程编程的基础内容,它们是并发编程的基石。 任务Runnable是一个接口...
Java多线程是Java编程中的重要概念,它允许程序同时执行多个任务,从而提高系统效率。在Java中,实现多线程主要有两种方式:通过继承Thread类和实现Runnable接口。Thread类提供了创建新线程的基本功能,而Runnable...
Java多线程是Java开发中的重要组成部分,它允许程序同时执行多个任务,提高..."Java多线程源码笔记.pdf"这样的文档通常会涵盖以上内容,并可能包含具体的源码分析和实战案例,对于理解和掌握Java多线程编程非常有帮助。
总结来说,Java多线程与线程安全实践涉及如何在多线程环境中有效管理共享资源,以避免潜在的并发问题。基于HTTP协议的断点续传则是一个实用的案例,展示了如何在实际项目中结合多线程技术来提高性能和用户体验。通过...
在Java编程领域,无锁编程是一种高级的并发控制技术,旨在提高多线程环境下的程序性能和可伸缩...学习这些内容,有助于开发者深入理解Java并发编程,提升在多线程环境下的编程能力,从而设计出更加高效、可扩展的系统。
在Java分布式应用开发中,多线程环境下的并发同步是至关重要的一个环节。并发同步器在多线程编程中起到协调各个线程访问共享资源,确保数据一致性与程序正确性的关键作用。本篇笔记将深入探讨Java中的并发同步机制,...
这本"Java并发编程学习笔记"可能是作者在深入研究Java并发特性、工具和最佳实践过程中积累的心得体会。下面,我们将根据这个主题,探讨一些关键的Java并发编程知识点。 1. **线程与进程**:在多任务环境中,线程是...
{8}多线程}{121}{chapter.8} {8.1}线程的常用属性与方法}{121}{section.8.1} {8.2}后台线程}{123}{section.8.2} {8.3}创建线程的两种方法}{123}{section.8.3} {8.4}Runnable}{123}{section.8.4} {8.5}Sleep...
Java并发编程是指在Java语言中编写多线程和多任务执行的程序,以便更高效地利用计算机的多核处理器资源。并发编程是Java高级编程技能中的重要组成部分,尤其是在需要处理大量数据、提供快速响应、实现高吞吐量和高可...
1. 多线程:理解ThreadLocal的使用必须建立在对多线程的理解基础上,包括线程的创建、执行、同步机制等。 2. 并发编程:ThreadLocal是解决并发问题的一种策略,它提供了一种避免共享状态的方式,减少了锁的使用。 3....
### Java分布式应用学习笔记03:JVM对线程的资源同步和交互机制 在深入探讨Java虚拟机(JVM)如何处理线程间的资源同步与交互机制之前,我们先来明确几个关键概念:线程、多线程、同步、并发以及它们在Java中的实现...
Java多线程编程是重要部分,JDK6提供了Thread类和Runnable接口,以及synchronized关键字、volatile变量和ThreadLocal等并发工具,帮助开发者构建高效、安全的并发程序。 总之,这份Java JDK6学习笔记将带你全面了解...
### Java并发编程实践笔记知识点详解 #### 一、保证线程安全的方法 ...以上是Java并发编程实践笔记中总结的关键知识点,涵盖了从基本概念到高级技术的应用,旨在帮助开发者构建高效、可靠的多线程应用。
以上就是Java源码笔记可能涉及的主要内容,通过深入学习这些知识点,开发者可以更好地理解和运用Java进行网络编程,提高软件开发的效率和质量。同时,对源码的深入理解也有助于解决实际问题,提升编程技能。
如并发工具类(如`java.util.concurrent`包中的`ExecutorService`、`Semaphore`等)和`java.lang.ThreadLocal`,以及`java.util.concurrent.atomic`包中的原子操作类,它们提供了更高效、更安全的多线程编程方式。...
9. **并发编程改进**:JDK 5.0引入了并发工具类,如`java.util.concurrent`包下的`ExecutorService`、`Future`、`Semaphore`等,以及`ThreadLocal`,增强了多线程编程的能力。 10. **内省(Introspection)**:JDK ...