【Java多线程与并发库】5.线程范围内共享变量的概念与作用
来源:互联网 发布:量化炒股软件 编辑:程序博客网 时间:2024/06/10 12:21
ThreadLocal的作用和目的,用于实现线程内的数据共享,即对于相同的程序代码,多个模块在
同一个线程中运行时要共享一份数据,而在另外线程中运行又共享另外一份数据。
线程范围内共享数据的示意图:
每个线程调用全局ThreadLocal对象的set方法,对相当于往其内部的map中增加一条记录,key
分别是各自的线程,value是各自的set方法传进去的值。在线程结束是可以调用ThreadLocal.clear()方法,
这样会更快释放内存,不调用也可以,因为线程结束后也可以自动释放相关的ThreadLocal变量。
ThreadLocal的应用场景:
(1)订单处理包括一系列操作:减少库存量、增加一条流水台账、修改总账,这几个操作要在同一个
事务中完成,通常也在同一个线程中进行处理,例如累加公司收款的操作失败了,则以应该把前面
的操作回滚,否则,提交所有操作,这要求这些操作使用相同的数据库连接对象,而这些操作的代
码分别位于不同的模块中。
(2)银行转账包含一系列操作:把转出账户的余额减少,把转入账户的余额增加,这两个操作要在同
一个事务中完成,它们必须使用相同的数据库连接对象,转入和转出操作的代码分别位于不同的账
户对象的方法。
(3)又比如,struts2的ActionContext,同一段代码被不同的线程调用运行时,该代码操作的数据是
每个线程各自的状态和数据,对于不同的线程来说,getContext方法拿到的对象都不相同,对于一个
线程来说,不管调用getContext方法多少次和在哪个模块中执行getContext方法,拿到的都已同一个。
我们接下来写一个线程范围内共享变量的实例:
首先我们先用两个线程获取同一个全局变量:
- package cn.edu.hpu.test;
- import java.util.Random;
- public class ThreadTest6 {
- private static int data=0;
- private static Random dandom=new Random();
- public static void main(String[] args) {
- for(int i=0;i<2;i++){
- new Thread(new Runnable(){
- public void run() {
- data=dandom.nextInt();
- System.out.println(Thread.currentThread().getName()
- +"放入数据:"+data);
- new A().get();
- new B().get();
- }
- }).start();
- }
- }
- static class A{
- public void get(){
- System.out.println("A 从"+Thread.currentThread().getName()
- +"中取的数据:"+data);
- }
- }
- static class B{
- public void get(){
- System.out.println("B 从"+Thread.currentThread().getName()
- +"中取的数据:"+data);
- }
- }
- }
可以看到,A类和B类两次取得的数据均为线程第二次获取的随机值,而不是每一次执行的值,
所以没有做到线程内生成的数据共享的功能。
我们来改进一下这个类:
我们使用一个Map来储存每个线程生成的data数据,然后设置key为每个线程本身,
在取数据的时候使用key去取每个线程的data数据。
- package cn.edu.hpu.test;
- import java.util.HashMap;
- import java.util.Map;
- import java.util.Random;
- public class ThreadTest6 {
- private static Random dandom=new Random();
- private static Map<Thread,Integer> threadData=new HashMap<Thread,Integer>();
- public static void main(String[] args) {
- for(int i=0;i<2;i++){
- new Thread(new Runnable(){
- public void run() {
- int data=dandom.nextInt();
- System.out.println(Thread.currentThread().getName()
- +"放入数据:"+data);
- threadData.put(Thread.currentThread(), data);
- new A().get();
- new B().get();
- }
- }).start();
- }
- }
- static class A{
- public void get(){
- System.out.println("A 从"+Thread.currentThread().getName()
- +"中取的数据:"+threadData.get(Thread.currentThread()));
- }
- }
- static class B{
- public void get(){
- System.out.println("B 从"+Thread.currentThread().getName()
- +"中取的数据:"+threadData.get(Thread.currentThread()));
- }
- }
- }
可以看到,每一个线程内生成的data数据我们都已经获取。
这样做到了每个线程内的数据进行了共享。
这种操作实际上在日常开发中就有接触,例如我们使用JDBC连接数据库,
如果所有操作数据库的类拿的都是同一个Connection,事务开始和结束都是在每个类
各自的线程中执行的,如果有一个线程刚刚开始添加数据,然后准备再删除一些数据的时候,
另外一个线程的事务做了commit操作,这就有可能导致第一个线程的事务也被Commit。
而使用了类似上面的线程数据共享机制,每一个线程都有其独立的,不与其他线程混杂在一起
的独立数据,就可以保证线程正常运行。
使用JDK5的ThreadLocal类可以更方便的实现线程内数据共享,具体请看下次总结。
出处:http://blog.csdn.net/acmman/article/details/52787078
- 【Java多线程与并发库】5.线程范围内共享变量的概念与作用
- 【Java多线程与并发库】5.线程范围内共享变量的概念与作用
- 【张孝祥并发课程笔记】04:线程范围内共享变量的概念与作用
- 多线程中范围内共享变量的概念与作用
- 线程范围内共享变量的概念与作用
- 线程范围内共享变量的概念与作用
- 线程范围内共享变量的概念与作用
- 线程范围内共享变量的概念与作用(五)
- 线程范围内共享变量的概念与作用(六)
- 线程范围内共享变量的概念与作用
- 线程范围内共享变量的概念与作用
- 05_张孝祥_Java多线程_线程范围内共享变量的概念与作用
- 【Java多线程与并发库】05 线程范围内共享变量ThreadLocal
- (4)传智播客_张孝祥_线程范围内共享变量的概念与作用
- (4)传智播客_张孝祥_线程范围内共享变量的概念与作用
- 线程范围内共享变量的概念与作用以及ThreadLocal类及应用修复bug
- java多线程范围内的共享变量
- JAVA 并发编程-线程范围内共享变量(五)
- 构建nodejs环境及解决node服务器外网端口无法访问
- 浅谈CORS(跨域资源分享),并给出Spring Security处理Preflight的方法
- ueditor的配置和使用
- 【独家】加入时间特征的船舶轨迹离线压缩算法——快速Douglas-Peucker算法研究
- 乔布斯的设计理念
- 【Java多线程与并发库】5.线程范围内共享变量的概念与作用
- Ubuntu 16.10上找回workspaces
- UITableView常用方法、属性总结
- 使用maven构建项目,项目上有红叉提示错误,但是错误找不到
- Manipulating Files With Tcl
- iOS常见问题之 cannot create __weak reference in file using manual reference counting
- MySQL Thread pool 操作过程
- tableview优化技巧
- 根据采购信息记录取得PO的含税单价(更改)