`
wang吖
  • 浏览: 238421 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

Java多线程-ThreadLocal-学习笔记9

 
阅读更多
一、概述
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多线程与并发库高级应用笔记概览 #### 一、Java多线程技术的重要性与挑战 Java线程技术是软件工程领域不可或缺的一部分,尤其在底层编程、Android应用开发以及游戏开发中,其重要性不言而喻。然而,...

    java多线程学习笔记

    在本文中,我们将深入探讨Java多线程的相关知识点,并结合提供的源代码进行学习。 1. **线程的创建** - **实现Runnable接口**:创建一个类实现Runnable接口,然后将其实例传递给Thread类的构造函数,如`Thread t =...

    Java多线程源码笔记.pdf

    Java多线程是Java编程中的重要概念,它允许程序同时执行多个任务,从而提高系统效率。在Java中,实现多线程主要有两种方式:通过继承Thread类和实现Runnable接口。Thread类提供了创建新线程的基本功能,而Runnable...

    java多线程相关资料整理

    Java多线程是Java开发中的重要组成部分,它允许程序同时执行多个任务,提高..."Java多线程源码笔记.pdf"这样的文档通常会涵盖以上内容,并可能包含具体的源码分析和实战案例,对于理解和掌握Java多线程编程非常有帮助。

    Java多线程与线程安全实践-基于Http协议的断点续传.zip

    总结来说,Java多线程与线程安全实践涉及如何在多线程环境中有效管理共享资源,以避免潜在的并发问题。基于HTTP协议的断点续传则是一个实用的案例,展示了如何在实际项目中结合多线程技术来提高性能和用户体验。通过...

    Java很好的学习笔记4 无锁.md,学习代码

    在Java编程领域,无锁编程是一种高级的并发控制技术,旨在提高多线程环境下的程序性能和可伸缩...学习这些内容,有助于开发者深入理解Java并发编程,提升在多线程环境下的编程能力,从而设计出更加高效、可扩展的系统。

    java分布式应用学习笔记05多线程下的并发同步器.pdf

    在Java分布式应用开发中,多线程环境下的并发同步是至关重要的一个环节。并发同步器在多线程编程中起到协调各个线程访问共享资源,确保数据一致性与程序正确性的关键作用。本篇笔记将深入探讨Java中的并发同步机制,...

    Java并发编程学习笔记.rar

    这本"Java并发编程学习笔记"可能是作者在深入研究Java并发特性、工具和最佳实践过程中积累的心得体会。下面,我们将根据这个主题,探讨一些关键的Java并发编程知识点。 1. **线程与进程**:在多任务环境中,线程是...

    Java学习笔记-个人整理的

    {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...

    threadLocal

    1. 多线程:理解ThreadLocal的使用必须建立在对多线程的理解基础上,包括线程的创建、执行、同步机制等。 2. 并发编程:ThreadLocal是解决并发问题的一种策略,它提供了一种避免共享状态的方式,减少了锁的使用。 3....

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

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

    Java JDK6学习笔记[ppt]

    Java多线程编程是重要部分,JDK6提供了Thread类和Runnable接口,以及synchronized关键字、volatile变量和ThreadLocal等并发工具,帮助开发者构建高效、安全的并发程序。 总之,这份Java JDK6学习笔记将带你全面了解...

    java并发编程实践笔记

    ### Java并发编程实践笔记知识点详解 #### 一、保证线程安全的方法 ...以上是Java并发编程实践笔记中总结的关键知识点,涵盖了从基本概念到高级技术的应用,旨在帮助开发者构建高效、可靠的多线程应用。

    java源码笔记

    以上就是Java源码笔记可能涉及的主要内容,通过深入学习这些知识点,开发者可以更好地理解和运用Java进行网络编程,提高软件开发的效率和质量。同时,对源码的深入理解也有助于解决实际问题,提升编程技能。

    良葛格java jdk 5.0学习笔记

    如并发工具类(如`java.util.concurrent`包中的`ExecutorService`、`Semaphore`等)和`java.lang.ThreadLocal`,以及`java.util.concurrent.atomic`包中的原子操作类,它们提供了更高效、更安全的多线程编程方式。...

    良葛格Java JDK 5.0学习笔记fuluB

    9. **并发编程改进**:JDK 5.0引入了并发工具类,如`java.util.concurrent`包下的`ExecutorService`、`Future`、`Semaphore`等,以及`ThreadLocal`,增强了多线程编程的能力。 10. **内省(Introspection)**:JDK ...

Global site tag (gtag.js) - Google Analytics