Package com.github.phantomthief.scope
Class Scope
java.lang.Object
com.github.phantomthief.scope.Scope
自定义Scope,支持如下功能:
- 开启一个自定义的Scope,在Scope范围内,可以通过
Scope各个方法读写数据 - 可以通过
supplyWithExistScope(com.github.phantomthief.scope.Scope, com.github.phantomthief.util.ThrowableSupplier<T, X>)或者runWithExistScope(com.github.phantomthief.scope.Scope, com.github.phantomthief.util.ThrowableRunnable<X>)绑定已经存在的scope
ScopeKey<String> TEST_KEY = allocate();
runWithNewScope(() -> {
TEST_KEY.set("abc");
String result = TEST_KEY.get(); // get "abc"
Scope scope = getCurrentScope();
executor.execute(wrapRunnableExistScope(scope, () -> {
String resultInScope = TEST_KEY.get(); // get "abc"
});
});
TODO: 当前实现是一种比较简易的方式,直接把所有Scope放到一个ThreadLocal里。
实际上这样在使用过程中会有二次hash查询的问题,对性能会有些许的影响,更好的做法是:
直接使用ThreadLocal(也就是使用内部的ThreadLocalMap),同时在Scope拷贝和清理时,维护一个额外的Set,进行ThreadLocal拷贝。
这样的优化考虑是:Scope正常访问的频率很高,而线程切换拷贝的概率比较低。
目前这个实现参考了 GRPC 的 Context API 以及 Spring 的 RequestContext,
相对比较简单,目前效率也可以接受。等到需要榨取性能时再对这个实现动手吧。
注意: 本实现并不充当对 ThreadLocal 性能提升的作用(虽然在有 FastThreadLocal 使用条件下并开启开关后,会优先使用 FastThreadLocal 以提升性能);
注意: 在Scope提供的传播已有Scope的方法中,没有对Scope做拷贝,如果使用supplyWithExistScope(Scope, ThrowableSupplier), runWithExistScope(Scope, ThrowableRunnable)
等方法在不同的线程传递Scope,那么多个线程会共享同一个Scope实例。
如果多个线程共享了一个Scope,那么他们对于ScopeKey的get/set调用是操作的同一个值,这一点和ThreadLocal不一样,ThreadLocal每个线程总是访问自己的一份变量。
因而,ScopeKey也不能在所有场合都无脑替换ThreadLocal。
- Author:
- w.vela
-
Constructor Summary
Constructors -
Method Summary
Modifier and TypeMethodDescriptionstatic Scope正常应该优先使用supplyWithNewScope(com.github.phantomthief.util.ThrowableSupplier<T, X>)或者runWithNewScope(com.github.phantomthief.util.ThrowableRunnable<X>)手工使用beginScope和endScope的场景只有在: 上面两个方法当需要抛出多个正交异常时会造成不必要的try/catch代码 开始scope和结束scope不在一个代码块中static voidendScope()static boolean<T> Tstatic Scopestatic <X extends Throwable>
voidrunWithExistScope(Scope scope, com.github.phantomthief.util.ThrowableRunnable<X> runnable) static <X extends Throwable>
voidrunWithNewScope(com.github.phantomthief.util.ThrowableRunnable<X> runnable) <T> voidstatic <T,X extends Throwable>
TsupplyWithExistScope(Scope scope, com.github.phantomthief.util.ThrowableSupplier<T, X> supplier) static <T,X extends Throwable>
TsupplyWithNewScope(com.github.phantomthief.util.ThrowableSupplier<T, X> supplier) static boolean
-
Constructor Details
-
Scope
public Scope()
-
-
Method Details
-
fastThreadLocalEnabled
@Beta public static boolean fastThreadLocalEnabled() -
tryEnableFastThreadLocal
@Beta public static boolean tryEnableFastThreadLocal()- Returns:
trueif fast thread local was enabled.
-
runWithExistScope
-
supplyWithExistScope
-
runWithNewScope
-
supplyWithNewScope
-
beginScope
正常应该优先使用supplyWithNewScope(com.github.phantomthief.util.ThrowableSupplier<T, X>)或者runWithNewScope(com.github.phantomthief.util.ThrowableRunnable<X>)手工使用beginScope和endScope的场景只有在:- 上面两个方法当需要抛出多个正交异常时会造成不必要的try/catch代码
- 开始scope和结束scope不在一个代码块中
- Throws:
IllegalStateException- if try to start a new scope in an exist scope.
-
endScope
public static void endScope()- See Also:
-
getCurrentScope
-
set
-
get
-