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 ...
随机推荐
- mac下安装配置java开发环境
可以使用homebrew下载相关软件,以下具体讲一下环境的配置: mac下安装jdk vi .bash_profile 输入i,进入编辑模式 输入以下配置,其中JAVA_HOME是你的jdk安装目录 ...
- 《大话操作系统——做坚实的project实践派》(2)
<大话操作系统--做坚实的project实践派>(2)
- codeforces 490 D Chocolate
题意:给出a1*b1和a2*b2两块巧克力,每次可以将这四个数中的随意一个数乘以1/2或者2/3,前提是要可以被2或者3整除,要求最小的次数让a1*b1=a2*b2,并求出这四个数最后的大小. 做法: ...
- Shiro 学习应用(续)
在前面的文章中为大家介绍了 Shrio 的基础概念.可能比較笼统.没有深入到开发过程的一些问题.如今集中在本帖中归纳一下有关问题. FormAuthenticationFilter 表单过滤器 表单过 ...
- POJ 2796 / UVA 1619 Feel Good 扫描法
Feel Good Description Bill is developing a new mathematical theory for human emotions. His recent ...
- VIM7.4 编译安装 开启python
https://github.com/wklken/k-vim ./configure --prefix=/usr/local/vim74 \--with-features=huge \--enabl ...
- 常见DDOS攻击原理和防御
常见的DDOS攻击主要分为流量型攻击和cc攻击: 流量型攻击主要通过发送大量的非法报文侵占正常业务带宽 包括SYN Flood/ SYN-ACK Flood /ACK Flood/ FIN/RST F ...
- BI中事实表与维度表的定义
一个典型的例子是,把逻辑业务比作一个立方体,产品维.时间维.地点维分别作为不同的坐标轴,而坐标轴的交点就是一个具体的事实.也就是说事实表是多个维度表的一个交点.而维度表是分析事实的一个窗口. 首先介绍 ...
- rel= "noopener"
rel= "noopener" <a href= "https://www.xiaogezi.cn/" target= "_blank" ...
- Function 和 eval 知识点总结
1 Function 1.1 函数的创建方式 1 函数声明 2 函数表达式 3 new Function // 1 function foo() {} // 2 var foo = function( ...