zoukankan      html  css  js  c++  java
  • 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--;
    		 }
    	 }
     }
    

    执行结果:

  • 相关阅读:
    CSS实现元素居中原理解析
    Windows 下 Ionic 开发环境搭建
    JavaScript实现简单的双向数据绑定
    JavaScript之Promise对象
    前端工程师的进阶之路
    前端开发必备之chrome插件
    Javascript之Event Loop
    CentOS7 如何挂载网络设备
    mysql 全量备份以及增量备份
    zabbix 内网监控云服务器
  • 原文地址:https://www.cnblogs.com/yunwuzhan/p/7079875.html
Copyright © 2011-2022 走看看