/* * JEF - Copyright 2009-2010 Jiyi (mr.jiyi@gmail.com) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package jef.tools.support; import java.lang.reflect.InvocationTargetException; import javax.management.ReflectionException; import jef.common.log.LogUtil; import jef.tools.reflect.BeanUtils; import jef.tools.reflect.MethodEx; /** * 编程中碰到一个问题,某个ThreadLocal为所有的线程保存的局部变量。 * 现在要在一个线程中操作另外一个线程中的局部变量。 * 从代码看java是为每个线程创建了一个threadlocalMap,将局部变量统一存在在这个map中。 * 糟糕的是相关的方法和变量都是包机私有的,所以为了突破限制,编写了这个类。 * 本类使用反射来突破安全性限制。并不是很好的方法。 * 一个可行的办法是自己编写整个 ThreadLocal的逻辑,用weakHashMap来存放数据。 * @author Administrator * * @param <T> */ public class ThreadLocal<T> extends java.lang.ThreadLocal<T>{ private static final Class<?> superClass=java.lang.ThreadLocal.class; private static boolean isForJDK6=System.getProperty("java.specification.version").startsWith("1.6"); private MethodEx getMethod; private MethodEx setMethod; public ThreadLocal(){ super(); } private void initMethod(Class<?> c){ if(getMethod==null){ getMethod=BeanUtils.getCompatibleMethod(c, (isForJDK6?"getEntry":"get"), superClass); } if(setMethod==null){ setMethod=BeanUtils.getCompatibleMethod(c, "set", superClass,Object.class); } } /** * JEF特有的方法,设置指定线程中的局部变量值 s * @param 参数 * @return void 返回类型 * @throws */ public void set(Thread t,T value){ try{ Object threadlocalMap = BeanUtils.invokeMethod(this, "getMap", t); if (threadlocalMap != null){ initMethod(threadlocalMap.getClass()); setMethod.invoke(threadlocalMap, this, value); }else{ MethodEx createMap=BeanUtils.getCompatibleMethod(superClass, "createMap", Thread.class,Object.class); createMap.invoke(this, t,value); } } catch (ReflectionException e) { LogUtil.exception(e); } catch (IllegalArgumentException e) { LogUtil.exception(e); } catch (IllegalAccessException e) { LogUtil.exception(e); } catch (InvocationTargetException e) { LogUtil.exception(e); } } /** * JEF特有的方法,获取指定线程中的局部变量值 s * @param 参数 * @return void 返回类型 * @throws */ @SuppressWarnings("unchecked") public T getExistValue(Thread t){ try{ Object threadlocalMap = BeanUtils.invokeMethod(this, "getMap", t); if (threadlocalMap != null){ initMethod(threadlocalMap.getClass()); if(isForJDK6){ Object entryObject=getMethod.invoke(threadlocalMap,this); return (T)BeanUtils.getFieldValue(entryObject, "value"); }else{ return (T)getMethod.invoke(threadlocalMap, this); } } return null; } catch (InvocationTargetException e) { throw new RuntimeException(e); } catch (ReflectionException e) { throw new RuntimeException(e); } catch (IllegalArgumentException e) { throw new RuntimeException(e); } catch (IllegalAccessException e) { throw new RuntimeException(e); } } }