转自:http://www.iteye.com/topic/103804
首先,ThreadLocal 不是用来解决共享对象的多线程访问问题的,一般情况下,通过ThreadLocal.set() 到线程中的对象是该线程自己使用的对象,其他线程是不需要访问的,也访问不到的。
各个线程中访问的是不同的对象。
另外,说ThreadLocal使得各线程能够保持各自独立的一个对象,并不是通过ThreadLocal.set()来实现的,而是通过每个线程中的new 对象 的操作来创建的对象,每个线程创建一个,不是什么对象的拷贝或副本。
通
过ThreadLocal.set()将这个新创建的对象的引用保存到各线程的自己的一个map中,每个线程都有这样一个map,执行
ThreadLocal.get()时,各线程从自己的map中取出放进去的对象,因此取出来的是各自自己线程中的对象,ThreadLocal实例是作
为map的key来使用的。
如果ThreadLocal.set()进去的东西本来就是多个线程共享的同一个对象,那么多个线程的ThreadLocal.get()取得的还是这个共享对象本身,还是有并发访问问题。
下面来看一个hibernate中典型的ThreadLocal的应用:
private static final ThreadLocal threadSession = new ThreadLocal();
public static Session getSession() throws InfrastructureException {
Session s = (Session) threadSession.get();
try {
if (s == null) {
s = getSessionFactory().openSession();
threadSession.set(s);
}
} catch (HibernateException ex) {
throw new InfrastructureException(ex);
}
return s;
}
可以看到在getSession()方法中,首先判断当前线程中有没有放进去session,如果还没有,那么通过
sessionFactory().openSession()来创建一个session,再将session
set到线程中,实际是放到当前线程的ThreadLocalMap这个map中,这时,对于这个session的唯一引用就是当前线程中的那个
ThreadLocalMap(下面会讲到),而threadSession作为这个值的key,要取得这个session可以通过
threadSession.get()来得到,里面执行的操作实际是先取得当前线程中的ThreadLocalMap,然后将
threadSession作为key将对应的值取出。这个session相当于线程的私有变量,而不是public的。
显然,其他线程中是取不到这个session的,他们也只能取到自己的ThreadLocalMap中的东西。要是session是多个线程共享使用的,那还不乱套了。
试想如果不用ThreadLocal怎么来实现呢?可能就要在action中创建session,然后把session一个个传到service
和dao中,这可够麻烦的。或者可以自己定义一个静态的map,将当前thread作为key,创建的session作为值,put到map中,应该也
行,这也是一般人的想法,但事实上,ThreadLocal的实现刚好相反,它是在每个线程中有一个map,而将ThreadLocal实例作为key,
这样每个map中的项数很少,而且当线程销毁时相应的东西也一起销毁了,不知道除了这些还有什么其他的好处。
总之,ThreadLocal不是用来解决对象共享访问问题的,而主要是提供了保持对象的方法和避免参数传递的方便的对象访问方式。归纳了两点:
1。每个线程中都有一个自己的ThreadLocalMap类对象,可以将线程自己的对象保持到其中,各管各的,线程可以正确的访问到自己的对象。
2。将一个共用的ThreadLocal静态实例作为key,将不同对象的引用保存到不同线程的ThreadLocalMap中,然后在线程执行
的各处通过这个静态ThreadLocal实例的get()方法取得自己线程保存的那个对象,避免了将这个对象作为参数传递的麻烦。
当然如果要把本来线程共享的对象通过ThreadLocal.set()放到线程中也可以,可以实现避免参数传递的访问方式,但是要注意
get()到的是那同一个共享对象,并发访问问题要靠其他手段来解决。但一般来说线程共享的对象通过设置为某类的静态变量就可以实现方便的访问了,似乎没
必要放到线程中。
ThreadLocal的应用场合,我觉得最适合的是按线程多实例(每个线程对应一个实例)的对象的访问,并且这个对象很多地方都要用到。
分享到:
相关推荐
在这个实验中,你可以通过创建多个线程,模拟并发执行,并在其中引发和处理异常,以此加深对Java多线程异常处理的理解。"源码"文件将包含实现这些概念的示例代码,而"要求"文件则会给出具体的实验任务和目标,帮助你...
### Java多线程编程总结 #### 一、Java线程:概念与原理 1. **操作系统中线程和进程的概念** - 当前的操作系统通常为多任务操作系统,多线程是实现多任务的一种...这些特性和概念对于理解Java多线程编程至关重要。
在Java编程中,多线程是并发处理任务的关键技术,特别是在服务器端开发和高并发场景下。本篇文章将深入探讨“最简单的线程安全问题”,并结合相关源码和工具来帮助理解。线程安全问题通常涉及到多个线程对共享资源的...
### Java多线程运算集合知识点解析 #### 一、Java多线程概念与原理 - **操作系统中的线程与进程**: - **进程**:指的是一个正在运行的应用程序,每个进程都拥有独立的内存空间。 - **线程**:是进程中的一个...
三、Java多线程防止非安全问题的策略 1. 使用不可变对象:如String、BigInteger、BigDecimal等都是不可变对象,可以在多线程中安全使用。自定义不可变对象也能有效防止非安全问题。 2. 线程局部变量(ThreadLocal...
通过这些实例,学习者能够深入理解Java多线程编程,提高解决实际并发问题的能力。每个章节的源码都是一个独立的案例,可以逐一研究,实践和调试,以便更好地掌握Java多线程编程技巧。在学习过程中,结合理论知识与...
Java中的多线程编程是开发高并发应用的关键技术之一,涉及到如何有效管理和利用系统资源,尤其是在处理并发数据访问时,确保数据的安全性和一致性至关重要。在Java中,有多种方式可以实现线程间的数据共享和对象独立...
在Java编程领域,多线程是一项至关重要...这些面试题和答案覆盖了Java多线程的核心知识点,有助于深入理解和掌握Java并发编程。在实际项目中,理解并熟练运用这些概念能够帮助开发者构建出更加高效、健壮的多线程应用。
总之,理解和掌握Java多线程编程是每个Java开发者必备的技能。正确地使用多线程可以提高程序的响应速度和并发能力,但也需要处理好线程安全和同步问题,以确保程序的正确性和稳定性。通过实践和学习,你可以编写出...
在Java编程中,多线程是一项关键特性,...总之,这个"JAVA多线程的一个带UI界面的例子"涵盖了Java多线程编程和GUI设计的核心概念,通过实际的代码示例,有助于开发者深入理解如何在实际应用中正确、高效地使用多线程。
### 正确理解ThreadLocal:深入解析其工作原理与应用场景 #### 一、ThreadLocal的基本概念 `ThreadLocal`是Java平台提供的一种线程局部变量的解决方案,它为每一个使用该变量的线程都提供了独立的变量副本,使得每...
Java多线程笔记 Java多线程笔记是 Java 编程语言中关于多线程编程的笔记,涵盖了线程基础知识、线程优先级、线程状态、守护线程、构造线程、线程中断等多方面的内容。 获取简单 main 程序中的线程 在 Java 中,...
首先,让我们深入理解Java多线程。Java通过Thread类和Runnable接口提供多线程支持。线程是程序执行的最小单元,每个线程都有自己的程序计数器、虚拟机栈、本地方法栈和一部分堆内存。创建新线程通常有两种方式:继承...
在Java编程中,多线程和线程安全是核心概念...总之,Java多线程与线程安全是提升应用程序性能和稳定性的关键。通过深入学习和实践,我们可以有效地在基于HTTP协议的环境中应用这些技术,构建出高效、健壮的多线程应用。
Java多线程是Java编程中的核心概念,它允许程序同时执行多个任务,提高了程序的效率和响应速度。本文将深入探讨Java多线程的相关知识点,包括线程的创建、线程的状态、同步机制以及线程安全问题。 1. **线程的创建*...
如`Atomic`系列(`AtomicInteger`、`AtomicLong`等)、`Callable`和`Future`接口,以及`ThreadLocal`,都是Java多线程编程中常用的安全工具。源代码会涵盖这些类和接口的使用场景。 总之,这份Java多线程设计模式源...
总结,Java 多线程编程涉及到线程的创建、状态转换、同步、通信以及线程池的使用等多个方面,理解和掌握这些知识点对于编写高效、安全的多线程程序至关重要。通过合理运用多线程技术,可以提升程序的并发性能,优化...
总结,`ThreadLocal`是Java中用于实现线程局部变量的工具,它提供了一种简单的方式在多线程环境下隔离数据,避免了传统的同步机制。但是,使用时需注意其潜在的内存泄漏风险和对代码可读性的影响,合理地选择使用...
在"23-多线程(02)"的压缩包中,很可能是进一步讲解了Java多线程的高级主题,如线程池的配置、并发集合(如ConcurrentHashMap、CopyOnWriteArrayList等)、线程局部变量(ThreadLocal)以及如何利用Future和...
总结起来,Java多线程和线程安全在实现基于HTTP协议的断点续传功能中起着关键作用。理解并掌握这些概念,可以帮助开发者构建高效、可靠的并发应用程序。在实际开发中,要时刻注意线程安全,避免潜在的问题,同时充分...