论坛首页 Java企业应用论坛

ThreadLocalizer

浏览 2998 次
锁定老帖子 主题:ThreadLocalizer
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
作者 正文
   发表时间:2007-05-27  
工作中写过一个ThreadLocalizer的小东西。目标是为了把“这个接口的access需要thread local”这个concern分离。

背景:
有一个TransactionManager(自制的transaction propagation,不推荐仿效)。众所周知Transaction propagation需要用thread local来管理。不过TransactionManagerImpl的代码已经够复杂了,不想再添加职责给他,所以决定假设TransactionManagerImpl只会在单线程中被调用:
interface TransactionManager {
  Transaction beginTransaction();
  void execute(String statementKey);
  ...
}
class TransactionManagerImpl implements TransactionManager {
  //many mutable fields
  ...
  //no synchronized, as we are blessed to be always in single thread.
}

既然TransactionManagerImpl不想管thread local,那么就得指望客户代码每次都是从thread local中取得TransactionManager了。

不过我们是Dependency Injection设计。给这些客户对象注射ThreadLocal<TransactionManager>用起来会比较麻烦。每次都要get()一下先,客户要很小心不要get之后在两个县城里面是用这个TransactionManager,比如:
...
TransactionManager man = threadLocal.get();
return new SomeOtherObject(man);//天知道这个SomeOtherObject会不会保证单线程。
...


另外ThreadLocal是很实现细节的东西,暴露给用户代码也很不好地。

所以,奇技淫巧一下,作了一个让同事苦笑摇头的ThreadLocalizer:
class ThreadLocalizer implements InvocationHandler {
  private final ThreadLocal local;
  ThreadLocalizer(ThreadLocal local) {
    this.local = local;
  }
  public Object invoke(Object proxy, Method mtd, Object[] args) {
    return mtd.invoke(local.get(), args);
  }
  public T as(Class<T> itf) {
    return Proxy.newProxyInstance(itf.getClassLoader(), new Class[]{itf}, this);
  }
}

然后,thread local这谁也不爱沾的脏活就可以交给Guice干了:
bind(TransactionManager.class).to(new Provider<TransactionManager> () {
  public TransactionManager get() {
    return new ThreadLocalizer(new ThreadLocal(){
      protected Object initialValue() {
        return new TransactionManagerImpl();
      }
    }).as(TransactionManager.class);
  }
}).in(Singleton.class);

实现代码和客户代码都清爽了。

这个其实和正在讨论的ThreadLocal关系不大,就是借这个热乎劲儿搀和一下。
   发表时间:2007-05-27  
ThreadLocalizer写成 abstract static 是不是好些呢?
不好意思,搞错了,忽略吧。


0 请登录后投票
   发表时间:2007-05-27  
Godlikeme 写道
ThreadLocalizer写成 abstract static 是不是好些呢?
不好意思,搞错了,忽略吧。



其实,我是有一个AbstractInterceptor类:
abstract class AbstractInterceptor implements InvocationHandler {
  protected abstract Object onInvoke(Object proxy, Method method, Object[] args) throws Throwable;
  protected abstract Object getForward();
  public Object invoke(Object proxy, Method method, Object[] args) throws Throwable{
    if(Object.class.equals(method.getDeclaringClass()) {
      //equals, toString, hashCode,special treatment
    }
    else {
      try {
        return onInvoke(proxy, method, args);
      }
      catch(InvocationTargetException e) {
        throw e.getTargetException();
      }
    }
  }
  public <T> T as(Class<T> itf) {
    return Proxy.newProxyInstance(itf.getClassLoader(), new Class[]{itf}, this);
  }
}

ThreadLocalizer只是继承了AbstractInterceptor,所以没法弄成static的。
0 请登录后投票
论坛首页 Java企业应用版

跳转论坛:
Global site tag (gtag.js) - Google Analytics