对struts2中ActionContext模拟及ThreadLocal的使用分析

struts2中,一个用户访问,对应一个线程,我们经常使用ActionContext来取Session,取我们特定线程的数据,那么,这一切究竟是怎样完成的呢,通过一个对struts2 ActionContext类的模拟,解释一下这个事情。

下面粗略的模拟了100个用户在5秒钟内随机访问系统的场景,以及对struts2中Session的使用

代码如下:


import java.util.HashMap;
import java.util.Map;
import java.util.Random;
/***
 * 
 * @author wjw
 * @since 2017-12-7
 */
public class ActionContext {

	static ThreadLocal<ActionContext> actionContext = new ThreadLocal<ActionContext>();
	private static final String SESSION = "session";
	private Map<String, Object> context;
	

	/***
	 * 取得当前线程的ActionContext对象
	 * @return
	 */
	public static ActionContext getContext(){
		
		return actionContext.get();
	}
	
	/***
	 * 设置当前线程context
	 * @param contextMap
	 */
	 public void setContextMap(Map<String, Object> contextMap) {
	        getContext().context = contextMap;
	    }
	
	/***
	 * set方法
	 * @param key
	 * @param value
	 */
	public void set(String key,String value){
		
		context.put(key, value);
	}
	
	
	/***
	 * get方法
	 * @param key
	 * @return
	 */
	public Object get(String key){
		return context.get(key);
		
	}
	
	
	/****
	 * 设置Session
	 * @param session
	 */
	 public void setSession(Map<String, Object> session) {
		 context.put(SESSION, session);
	 }
	
	/***
	 * 模拟通过ActionContext获取Session方法
	 * @return
	 */
	public Map<String,Object> getSession(){
		return (Map<String, Object>) context.get(SESSION);
		
	}
	
	
	public static void main(String[] args) {
		//模拟一百个线程访问系统,先设置Session(此操作由Struts2完成),再取出Session(此操作一般由程序员编写代码)
		for(int i = 0; i < 100; i++){
		//线程一访问系统
		new Thread(new Runnable(){

			@Override
			public void run() {
				// TODO Auto-generated method stub
				Map<String,Object> session = new HashMap<String,Object>();
				session.put(Thread.currentThread().getName(), "我是 " + Thread.currentThread().getName() +" 线程中的session!");
				
				//设置特定线程的特定ActionContext对象(struts2完成)
				ActionContext tempActionContext = new ActionContext();
				actionContext.set(tempActionContext);
				ActionContext.getContext().setContextMap(new HashMap<String, Object>());
				
				//设置Sesion(struts2完成)
				ActionContext.getContext().setSession(session);
				
				
				//睡一会儿
				try {
					Thread.sleep(new Random().nextInt(5)*1000);
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
				
				
				Map<String,Object> session2 = ActionContext.getContext().getSession();
				System.out.println(Thread.currentThread().getName() + ":" +(String)session2.get(Thread.currentThread().getName()));
			}
			
			
		}).start();
		
		}
		
		
		
		
		
		
		
	}
}

运行结果:

Thread-4:我是 Thread-4 线程中的session!
Thread-0:我是 Thread-0 线程中的session!
Thread-5:我是 Thread-5 线程中的session!
Thread-1:我是 Thread-1 线程中的session!
Thread-12:我是 Thread-12 线程中的session!
Thread-35:我是 Thread-35 线程中的session!
Thread-36:我是 Thread-36 线程中的session!
Thread-43:我是 Thread-43 线程中的session!
Thread-45:我是 Thread-45 线程中的session!
Thread-50:我是 Thread-50 线程中的session!
Thread-52:我是 Thread-52 线程中的session!
Thread-58:我是 Thread-58 线程中的session!
Thread-60:我是 Thread-60 线程中的session!
Thread-72:我是 Thread-72 线程中的session!
Thread-75:我是 Thread-75 线程中的session!
Thread-84:我是 Thread-84 线程中的session!
Thread-85:我是 Thread-85 线程中的session!
Thread-94:我是 Thread-94 线程中的session!
Thread-97:我是 Thread-97 线程中的session!
Thread-15:我是 Thread-15 线程中的session!
Thread-3:我是 Thread-3 线程中的session!
Thread-21:我是 Thread-21 线程中的session!
Thread-20:我是 Thread-20 线程中的session!
Thread-37:我是 Thread-37 线程中的session!
Thread-29:我是 Thread-29 线程中的session!
Thread-32:我是 Thread-32 线程中的session!
Thread-30:我是 Thread-30 线程中的session!
Thread-28:我是 Thread-28 线程中的session!
Thread-41:我是 Thread-41 线程中的session!
Thread-47:我是 Thread-47 线程中的session!
Thread-46:我是 Thread-46 线程中的session!
Thread-44:我是 Thread-44 线程中的session!
Thread-53:我是 Thread-53 线程中的session!
Thread-48:我是 Thread-48 线程中的session!
Thread-55:我是 Thread-55 线程中的session!
Thread-65:我是 Thread-65 线程中的session!
Thread-66:我是 Thread-66 线程中的session!
Thread-64:我是 Thread-64 线程中的session!
Thread-73:我是 Thread-73 线程中的session!
Thread-78:我是 Thread-78 线程中的session!
Thread-81:我是 Thread-81 线程中的session!
Thread-77:我是 Thread-77 线程中的session!
Thread-92:我是 Thread-92 线程中的session!
Thread-96:我是 Thread-96 线程中的session!
Thread-7:我是 Thread-7 线程中的session!
Thread-2:我是 Thread-2 线程中的session!
Thread-16:我是 Thread-16 线程中的session!
Thread-25:我是 Thread-25 线程中的session!
Thread-18:我是 Thread-18 线程中的session!
Thread-23:我是 Thread-23 线程中的session!
Thread-38:我是 Thread-38 线程中的session!
Thread-42:我是 Thread-42 线程中的session!
Thread-49:我是 Thread-49 线程中的session!
Thread-54:我是 Thread-54 线程中的session!
Thread-56:我是 Thread-56 线程中的session!
Thread-67:我是 Thread-67 线程中的session!
Thread-68:我是 Thread-68 线程中的session!
Thread-79:我是 Thread-79 线程中的session!
Thread-74:我是 Thread-74 线程中的session!
Thread-86:我是 Thread-86 线程中的session!
Thread-89:我是 Thread-89 线程中的session!
Thread-87:我是 Thread-87 线程中的session!
Thread-99:我是 Thread-99 线程中的session!
Thread-8:我是 Thread-8 线程中的session!
Thread-11:我是 Thread-11 线程中的session!
Thread-6:我是 Thread-6 线程中的session!
Thread-27:我是 Thread-27 线程中的session!
Thread-24:我是 Thread-24 线程中的session!
Thread-26:我是 Thread-26 线程中的session!
Thread-40:我是 Thread-40 线程中的session!
Thread-31:我是 Thread-31 线程中的session!
Thread-51:我是 Thread-51 线程中的session!
Thread-62:我是 Thread-62 线程中的session!
Thread-61:我是 Thread-61 线程中的session!
Thread-57:我是 Thread-57 线程中的session!
Thread-59:我是 Thread-59 线程中的session!
Thread-70:我是 Thread-70 线程中的session!
Thread-82:我是 Thread-82 线程中的session!
Thread-80:我是 Thread-80 线程中的session!
Thread-71:我是 Thread-71 线程中的session!
Thread-93:我是 Thread-93 线程中的session!
Thread-98:我是 Thread-98 线程中的session!
Thread-95:我是 Thread-95 线程中的session!
Thread-90:我是 Thread-90 线程中的session!
Thread-10:我是 Thread-10 线程中的session!
Thread-13:我是 Thread-13 线程中的session!
Thread-14:我是 Thread-14 线程中的session!
Thread-9:我是 Thread-9 线程中的session!
Thread-17:我是 Thread-17 线程中的session!
Thread-19:我是 Thread-19 线程中的session!
Thread-22:我是 Thread-22 线程中的session!
Thread-33:我是 Thread-33 线程中的session!
Thread-34:我是 Thread-34 线程中的session!
Thread-39:我是 Thread-39 线程中的session!
Thread-69:我是 Thread-69 线程中的session!
Thread-63:我是 Thread-63 线程中的session!
Thread-83:我是 Thread-83 线程中的session!
Thread-76:我是 Thread-76 线程中的session!
Thread-91:我是 Thread-91 线程中的session!
Thread-88:我是 Thread-88 线程中的session!


分析:

我先为当前线程初始化一个特定ActionContext对象,将其保存到ThreadLocal中,ActionContext对象通过一个map集合保存数据,而session又保存在map集合中。

使用的时候,通过ActionContext静态方法getContext()取得这个特定的ActionContext对象,里面的map集合就保存了当前线程的特定数据。

每一个访问是一个线程,每一个线程有一个特定ActionContext对象,也就有一份特定的map数据。

通过ThreadLocal取得当前线程的特定ActionContext对象。

通过结果,可以看出,各线程数据各归其位,各司其职。

主要细细体会ThreadLocal的用法。



如有错误,欢迎指正

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值