Java多线程10:ThreadLocal的作用及使用
来源:互联网 发布:在线seo外链工具软件 编辑:程序博客网 时间:2024/05/29 16:31
ThreadLocal的作用
从上一篇对于ThreadLocal的分析来看,可以得出结论:ThreadLocal不是用来解决共享对象的多线程访问问题的,通过ThreadLocal的set()方法设置到线程的ThreadLocal.ThreadLocalMap里的是是线程自己要存储的对象,其他线程不需要去访问,也是访问不到的。各个线程中的ThreadLocal.ThreadLocalMap以及ThreadLocal.ThreadLocal中的值都是不同的对象。
至于为什么要使用ThreadLocal,不妨这么考虑这个问题。Java Web中,写一个Servlet:
public class Servlet extends HttpServlet{ protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { this.doGet(request, response); } protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { }}
我在一个普通JavaBean内想拿到这个HttpServletRequest,但是无法通过参数传递的方式:
public class OperateRequest{ public String operateRequest() { return null; }}
这时候怎么办?第一个解决方案,Servlet类中定义一个全局的HttpServletRequest,至于怎么定义就随便了,可以定义成静态的,也可以定义成非静态的但是对外提供setter/getter,然后operateRequest()方法每次都取这个全局的HttpServletRequest就可以了。
不否认,这是一种可行的解决方案,但是这种解决方案有一个很大的缺点:竞争。既然HttpServletRequest是全局的,那势必要引入同步机制来保证线程安全性,引入同步机制意味着牺牲响应给用户的时间----这在注重与用户之间响应的Java Web中是难以容忍的。
所以,我们引入ThreadLocal,既然ThreadLocal.ThreadLocalMap是线程独有的,别的线程访问不了也没必要访问,那我们通过ThreadLocal把HttpServletRequest设置到线程的ThreadLocal.ThreadLocalMap里面去不就好了?这样,在一次请求中哪里需要用到HttpServletRequest,就使用ThreadLocal的get()方法就把这个HttpServletRequest给取出来了,是不是一个很好的解决方案呢?
ThreadLocal使用
忘记上面那个复杂的问题,我们来看一下ThreadLocal的简单使用,首先ThreadLocal肯定是全局共享的:
public class Tools{ public static ThreadLocal<String> t1 = new ThreadLocal<String>();}
写一个线程往ThreadLocal里面塞值:
public class ThreadLocalThread extends Thread{ private static AtomicInteger ai = new AtomicInteger(); public ThreadLocalThread(String name) { super(name); } public void run() { try { for (int i = 0; i < 3; i++) { Tools.t1.set(ai.addAndGet(1) + ""); System.out.println(this.getName() + " get value--->" + Tools.t1.get()); Thread.sleep(200); } } catch (InterruptedException e) { e.printStackTrace(); } }}
写个main函数,启动三个ThreadLocalThread:
public static void main(String[] args) throws Exception { ThreadLocalThread a = new ThreadLocalThread("ThreadA"); ThreadLocalThread b = new ThreadLocalThread("ThreadB"); ThreadLocalThread c = new ThreadLocalThread("ThreadC"); a.start(); b.start(); c.start(); }
看一下运行结果:
ThreadA get value--->1ThreadC get value--->2ThreadB get value--->3ThreadB get value--->4ThreadC get value--->6ThreadA get value--->5ThreadC get value--->8ThreadA get value--->7ThreadB get value--->9
看到每个线程的里都有自己的String,并且互不影响----因为绝对不可能出现数字重复的情况。用一个ThreadLocal也可以多次set一个数据,set仅仅表示的是线程的ThreadLocal.ThreadLocalMap中table的某一位置的value被覆盖成你最新设置的那个数据而已,对于同一个ThreadLocal对象而言,set后,table中绝不会多出一个数据。
ThreadLocal再总结
上一篇文章的最后有对ThreadLocal的工作原理进行总结,这里对ThreadLocal再次进行一个总结:
1、ThreadLocal不是集合,它不存储任何内容,真正存储数据的集合在Thread中。ThreadLocal只是一个工具,一个往各个线程的ThreadLocal.ThreadLocalMap中table的某一位置set一个值的工具而已
2、同步与ThreadLocal是解决多线程中数据访问问题的两种思路,前者是数据共享的思路,后者是数据隔离的思路
3、同步是一种以时间换空间的思想,ThreadLocal是一种空间换时间的思想
4、ThreadLocal既然是与线程相关的,那么对于Java Web来讲,ThreadLocal设置的值只在一次请求中有效,是不是和request很像?因为request里面的内容也只在一次请求有效,对比一下二者的区别:
(1)ThreadLocal只能存一个值,一个Request由于是Map形式的,可以用key-value形式存多个值
(2)ThreadLocal一般用在框架,Request一般用在表示层、Action、Servlet
- Java多线程10:ThreadLocal的作用及使用
- ThreadLocal的作用与使用
- ThreadLocal多线程通信的使用
- Java多线程编程--(4)ThreadLocal的使用
- Java多线程编程--(4)ThreadLocal的使用
- Java多线程编程--(4)ThreadLocal的使用
- JAVA多线程-线程间通信(五)-类ThreadLocal的使用
- Java多线程之ThreadLocal和InheritableThreadLocal的使用
- java ThreadLocal的使用
- Java ThreadLocal的使用
- 【Java ThreadLocal的使用】
- Java ThreadLocal的使用
- JAVA Threadlocal 的使用
- Java ThreadLocal的使用
- Java ThreadLocal的使用
- ThreadLocal的使用及实现
- java线程中ThreadLocal类的使用及介绍
- Java线程:ThreadLocal类的作用
- Java多线程9:ThreadLocal源码剖析
- Session 实现机制
- 兼容Android的html5移动端视频播放video自动播放/隐藏播放控件
- JDK源码走读(3):容器之ArrayList
- 第十九周—c语言 电子词典项目
- Java多线程10:ThreadLocal的作用及使用
- 素数求积
- 避免Toast多次弹出
- C++11智能指针之unique_ptr
- 中文乱码专题
- Java多线程11:ReentrantLock的使用和Condition
- 内网 外网发布
- STM32F4-IAP学习笔记(一)
- java参数传递