Java ThreadLocal示例及使用方法总结
2012-03-01 10:48
891 查看
一、概述
ThreadLocal的名称比较容易让人误解,会认为其是一个“本地线程”。其实,ThreadLocal并不是一个Thread,而是Thread的局部变量。
其设计的初衷是为了解决多线程编程中的资源共享问题。提起这个,大家一般会想到synchronized,synchronized采取的是“以时间换空间”的策略,本质上是对关键资源上锁,让大家排队操作。而ThreadLocal采取的是“以空间换时间”的思路,为每个使用该变量的线程提供独立的变量副本,在本线程内部,它相当于一个“全局变量”,可以保证本线程任何时间操纵的都是同一个对象。
二、实例
下面用一个实例阐述ThreadLocal的使用方法
创建一个Context类,其中含有transactionId属性。
创建MyThreadLocal做为容器,将一个Context对象保存于ThreadLocal中
多线程客户端程序,用于测试
模拟业务层,在某处读取context对象
程序输出:
三、总结
ThreadLocal使用步骤
1.建立ThreadLocal容器对象A,其中对需要保存的属性进行封装。并提供相应的get/set方法(全部为static)
2.在客户端程序中,用A.setxxx, A.getXXX访问相应数据,即可保证每个线程访问的是自己独立的变量
参考文献:
1. http://lavasoft.blog.51cto.com/62575/51926/
2. http://veerasundar.com/blog/2010/11/java-thread-local-how-to-use-and-code-sample/
ThreadLocal的名称比较容易让人误解,会认为其是一个“本地线程”。其实,ThreadLocal并不是一个Thread,而是Thread的局部变量。
其设计的初衷是为了解决多线程编程中的资源共享问题。提起这个,大家一般会想到synchronized,synchronized采取的是“以时间换空间”的策略,本质上是对关键资源上锁,让大家排队操作。而ThreadLocal采取的是“以空间换时间”的思路,为每个使用该变量的线程提供独立的变量副本,在本线程内部,它相当于一个“全局变量”,可以保证本线程任何时间操纵的都是同一个对象。
二、实例
下面用一个实例阐述ThreadLocal的使用方法
创建一个Context类,其中含有transactionId属性。
package com.vigar; public class Context { private String transactionId = null; public String getTransactionId() { return transactionId; } public void setTransactionId(String transactionId) { this.transactionId = transactionId; } }
创建MyThreadLocal做为容器,将一个Context对象保存于ThreadLocal中
package com.vigar; public class MyThreadLocal { public static final ThreadLocal userThreadLocal = new ThreadLocal(); public static void set(Context user) { userThreadLocal.set(user); } public static void unset() { userThreadLocal.remove(); } public static Context get() { return (Context)userThreadLocal.get(); } }
多线程客户端程序,用于测试
package com.vigar; import java.util.Random; public class ThreadLocalDemo extends Thread { public static void main(String[] args) { Thread threadOne = new ThreadLocalDemo(); threadOne.start(); Thread threadTwo = new ThreadLocalDemo(); threadTwo.start(); } @Override public void run() { // 线程 Context context = new Context(); Random random = new Random(); int age = random.nextInt(100); context.setTransactionId(String.valueOf(age)); System.out.println("set thread ["+getName()+"] contextid to " + String.valueOf(age)); // 在ThreadLocal中设置context MyThreadLocal.set(context); /* note that we are not explicitly passing the transaction id */ try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } new BusinessService().businessMethod(); MyThreadLocal.unset(); } }
模拟业务层,在某处读取context对象
package com.vigar; public class BusinessService { public void businessMethod() { Context context = MyThreadLocal.get(); System.out.println(context.getTransactionId()); } }
程序输出:
set thread [Thread-0] contextid to 32 set thread [Thread-1] contextid to 89 32 89
三、总结
ThreadLocal使用步骤
1.建立ThreadLocal容器对象A,其中对需要保存的属性进行封装。并提供相应的get/set方法(全部为static)
2.在客户端程序中,用A.setxxx, A.getXXX访问相应数据,即可保证每个线程访问的是自己独立的变量
参考文献:
1. http://lavasoft.blog.51cto.com/62575/51926/
2. http://veerasundar.com/blog/2010/11/java-thread-local-how-to-use-and-code-sample/
相关文章推荐
- Java使用Socket通信传输文件的方法示例
- Java使用正则表达式提取XML节点内容的方法示例
- java ThreadLocal使用方法
- Json学习总结(1)——Java和JavaScript中使用Json方法大全
- Java中遍历Map的多种方法示例及优缺点总结
- Java中的修饰词使用方法总结
- Java equals()方法使用详解及总结
- HBase总结(十一)hbase Java API 介绍及使用示例
- C#匿名委托和Java匿名局部内部类使用方法示例
- Java使用正则表达式匹配获取链接地址的方法示例
- Java中使用DOM和SAX解析XML文件的方法示例
- Java使用正则表达式删除所有HTML标签的方法示例
- JAVA代理方式使用示例总结
- 两种模型选择和超参数调整方法及Spark MLlib使用示例(Scala/Java/Python)
- HBase总结(十一)hbase Java API 介绍及使用示例
- Java反射基本使用方法 示例
- HBase总结(十一)hbase Java API 介绍及使用示例
- java中使用jdbcTemplate的query方法举例与总结
- Java私有构造器使用方法示例
- java基础总结 -- 泛型 在类、接口、方法、匿名类、元组等使用 堆栈例子 商店模型