Java ThreadLocal类学习
ThreadLocal为线程局部变量,通过线程名(key)-对象(value)的Map来获取每个线程对应的对象。我们不能通过ThreadLocal处理多线程并发问题,但是每个线程可以通过ThreadLocal轻易的访问到自己保存的对象。
以Hibernate中sessionFactory,Session举例
在Hibernate中sessionFactory是线程安全,在web应用中只要有一份实例就行,但是Session是每个线程都各自拥有一份实例,不然不同的线程持有同一个session对象进行CRUD,会引起数据操作混乱。因此为每一个线程都分配一个独自的Session实例,这里可以应用了ThreadLocal。下面进行简单模拟,说明ThreadLocal使用
//SessioinFactory类保存一个自定义的ThreadLocalSessionContext对象
package com.localthread;
public class SessionFactory {
public ThreadLocalSessionContext sc;
public SessionFactory(){
sc= new ThreadLocalSessionContext(this);
}
public Session currentSession(){
return sc.currentSession();
}
public Session createSession(){
return new Session();
}
}
package com.localthread;
import java.util.HashMap;
import java.util.Map;
//使用ThreadLocal来保存一个以SessionFactory-Session为key-value的Map。
public class ThreadLocalSessionContext {
private SessionFactory sessionFactory;
public ThreadLocalSessionContext(SessionFactory sessionFactory){this.sessionFactory=sessionFactory;}
public SessionFactory factory(){return sessionFactory;}
private static final ThreadLocal<Map> CONTEXT_TL=new ThreadLocal();//应用ThreadLocal,其中的Map的SessionFactory(key)-Session(value)
//获得当前线程的Session,没有则用SessioinFactory创建一个
public final Session currentSession(){
Session session=exsitSession(factory());
if(session==null){
session=factory().createSession();
bind(factory(),session);
}
return session;
}
public static Map sessionMap(){
return CONTEXT_TL.get();
}
public static Session exsitSession(SessionFactory factory){
Map sessionMap=sessionMap();
if(sessionMap==null)
return null;
return (Session) sessionMap.get(factory);
}
public static void bind(SessionFactory factory,Session session){
Map sessionMap=sessionMap();
if(sessionMap==null){
sessionMap=new HashMap();
CONTEXT_TL.set(sessionMap);
}
sessionMap.put(factory, session);
}
}
package com.localthread;
//打印sessionId
public class Session {
public int sessionId=0;
public void print(){
System.out.println(Thread.currentThread().getName()+":"+this+",sessionId:"+sessionId++);
}
}
//测试类
/***
启动三个线程共享一个SessionFactory,在每个线程的Run方法中获得每个线程各自对应的Session,测试输出如下图:
其中SessionId++按照预期运行。
**/
package com.localthread;
public class Main {
public static void main(String[] args) {
SessionFactory factory=new SessionFactory();
SessionThread s1=new SessionThread(factory);
SessionThread s2=new SessionThread(factory);
SessionThread s3=new SessionThread(factory);
s1.start();s2.start();s3.start();
}
}
class SessionThread extends Thread{
private int count=5;
private SessionFactory factory;
public SessionThread(SessionFactory factory){
this.factory=factory;
}
public void run(){
while(count>0){
factory.currentSession().print();
count--;
}
}
}
执行结果:

Java ThreadLocal类学习的更多相关文章
- Java常用类学习笔记总结
Java常用类 java.lang.String类的使用 1.概述 String:字符串,使用一对""引起来表示. 1.String声明为final的,不可被继承 2.String ...
- ThreadLocal类学习笔记
这个类在java1.2中就出现了,线程独有的变量(每个线程都有一份变量),使用它的好处之一就是可以少传许多参数. 在哪里用到它呢?有连接池的地方就有它的身影,连接池包括数据库连接池,网络连接池等. i ...
- 学习笔记:因为java匿名类学习到接口的一些小用法
在看CometD的示例代码时发现了许多有意思的代码,但说实话看别人的代码确实是件很累的事情,所以就看到这个知识点做一下记录吧. 先看一段代码: 代码1 这段代码中有一个new的操作,而且是在方 ...
- java基础知识回顾之java Thread类学习(八)--java.util.concurrent.locks(JDK1.5)与synchronized异同讲解
看API文档介绍几个方法: JDK1.5中提供了多线程的升级解决方案: 特点: 1.将同步synchronized显示的替换成Lock 2.接口Conditio ...
- java基础知识回顾之java Thread类学习(八)--java多线程通信等待唤醒机制经典应用(生产者消费者)
*java多线程--等待唤醒机制:经典的体现"生产者和消费者模型 *对于此模型,应该明确以下几点: *1.生产者仅仅在仓库未满的时候生产,仓库满了则停止生产. *2.消费者仅仅在有产品的时 ...
- java基础知识回顾之java Thread类学习(三)--java线程实现常见的两种方式实现好处:
总结:实现Runnable接口比继承Thread类更有优势: 1.因为java只能单继承,实现Runnable接口可以避免单继承的局限性 2.继承Thread类,多个线程不能处理或者共享同一个资源,但 ...
- Java Math类学习
1. java.lang.Math Math类其成员皆为静态成员(static),无需创建对象,直接用类名Math作为前缀使用它们即可. 2. Math类有两个静态常量:E(自然对数)和PI(圆周 ...
- java arrays类学习
java.util.Arrays类能方便地操作数组,它提供的所有方法都是静态的. 具有以下功能: (1)给数组赋值:通过fill方法. (2)对数组排序:通过sort方法,按升序. (3)比较数组:通 ...
- java工具类学习整理——集合
好久没有总结一些东西了,同时集合部分的知识点也学习的比较早了,但是从来没有抽时间去研究和学习,今天正好有时间就总结一下map常用的遍历方法: package runningwhile; import ...
随机推荐
- CCEditBox/CCEditBoxImpl
#ifndef __CCEditBoxIMPL_H__ #define __CCEditBoxIMPL_H__ #include "cocos2d.h" #include &quo ...
- HDU 2045不easy系列之三LELE的RPG难题(趋向于DP的递推)
不easy系列之(3)-- LELE的RPG难题 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Ot ...
- NHibernate之旅(14):探索NHibernate中使用视图
本节内容 引入 1.持久化类 2.映射文件 3.測试 结语 引入 在数据库操作中,我们除了对表操作,还有视图.存储过程等操作,这一篇和下篇来学习这些内容.这篇我们来学习怎样在NHibernate中使用 ...
- iOS库--.a与.framework
一.什么是库? 库是共享程序代码的方式,一般分为静态库和动态库. 二.静态库与动态库的差别? 静态库:链接时完整地拷贝至可运行文件里.被多次使用就有多份冗余拷贝. 动态库:链接时不复制.程序执行时由系 ...
- oracle rac下调节redo log file 文件大小
rac下调节redo log file 文件大小 (1)查看当前日志信息: select * from v$logfile; (步骤2中得路径能够在这里MEMBER列看到,redo文件名称自己命名.比 ...
- LCA 近期公共祖先 小结
LCA 近期公共祖先 小结 以poj 1330为例.对LCA的3种经常使用的算法进行介绍,分别为 1. 离线tarjan 2. 基于倍增法的LCA 3. 基于RMQ的LCA 1. 离线tarjan / ...
- TS2
//还要注意的是,在构造函数的参数上使用public等同于创建了同名的成员变量. class Student { fullName: string; constructor(public firstN ...
- OAuth2建立webapi认证服务供自己的客户端使用--密码模式
场景:你自己实现了一套webApi,想供自己的客户端调用,又想做认证. 第一步:通过vs2015建立web api项目,Startup.cs,这个类将会作为Owin的启动类. 第二步:在webapi. ...
- P2216 [HAOI2007]理想的正方形(二维RMQ)
题目描述 有一个a*b的整数组成的矩阵,现请你从中找出一个n*n的正方形区域,使得该区域所有数中的最大值和最小值的差最小. 输入输出格式 输入格式: 第一行为3个整数,分别表示a,b,n的值 第二行至 ...
- 阿里云Maven中央仓库配置
方式一:统一配置 在maven安装目录/conf下的settings.xml 文件里配置mirrors的子节点,添加如下mirror <mirror> <id>alimaven ...