gpt4 book ai didi

multithreading - Groovy类别的使用仅限于当前线程是什么意思?

转载 作者:行者123 更新时间:2023-12-03 13:19:01 25 4
gpt4 key购买 nike

我在 Groovy In Action,第二版一书中找到了以下语句:

Category use is confined to the current thread



这句话实际上是什么意思?

最佳答案

这意味着您只能在同一线程中调用通过类别类添加的方法。考虑以下示例:

class StringUtils {
static String transform(String source) {
return source.toUpperCase().reverse().substring(0, source.length() / 2 as int)
}
}

use (StringUtils) {
println "Lorem ipsum".transform()
}

在此示例中,我们通过类别添加了 String.transform()方法。运行此示例将产生以下输出:
MUSPI

在此示例中,我们在 main线程中使用了类别类,并且在 String.transform()线程中也调用了 main方法。

现在让我们稍微改变一下这个例子,在 String.transform()线程之外调用 main方法,方法是在新启动的线程中调用它:
class StringUtils {
static String transform(String source) {
return source.toUpperCase().reverse().substring(0, source.length() / 2 as int)
}
}

use (StringUtils) {
Thread.start {
println "Lorem ipsum".transform()
}
}

我们在 StringUtil线程中使用了 main类别类,并从 Thread-1线程中调用了此方法。让我们看看运行它会发生什么:
Exception in thread "Thread-1" groovy.lang.MissingMethodException: No signature of method: java.lang.String.transform() is applicable for argument types: () values: []
at org.codehaus.groovy.runtime.ScriptBytecodeAdapter.unwrap(ScriptBytecodeAdapter.java:58)
at org.codehaus.groovy.runtime.callsite.PojoMetaClassSite.call(PojoMetaClassSite.java:49)
at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:48)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:113)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:117)
at script$_run_closure1$_closure2.doCall(script.groovy:9)
at script$_run_closure1$_closure2.doCall(script.groovy)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:93)
at groovy.lang.MetaMethod.doMethodInvoke(MetaMethod.java:325)
at org.codehaus.groovy.runtime.metaclass.ClosureMetaClass.invokeMethod(ClosureMetaClass.java:294)
at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1022)
at groovy.lang.Closure.call(Closure.java:414)
at groovy.lang.Closure.call(Closure.java:408)
at groovy.lang.Closure.run(Closure.java:495)
at java.lang.Thread.run(Thread.java:748)

引发异常,因为 String.transform()Thread-1线程的范围内不存在-它仅存在于 main线程中。

但是,让我们假设我们必须使这种方法在 Thread-1线程范围内可用。我们可以通过在 use(StringUtils){}块内定义 Thread-1来实现这一目标,例如
class StringUtils {
static String transform(String source) {
return source.toUpperCase().reverse().substring(0, source.length() / 2 as int)
}
}

Thread.start {
use(StringUtils) {
println "Lorem ipsum".transform()
}
}

现在一切都好了-在 Thread-1中定义了类别用法块,我们从同一线程调用 String.transform()方法。运行此示例将向控制台产生预期的输出:
MUSPI

这是什么

Category use is confined to the current thread



在实践中是指。

但是如何调用此方法?

当我们调用:
"Lorem ipsum".transform()

从上面的示例中,下面的Groovy方法处理 transform()方法的调用:
groovy.lang.MetaClassImpl.invokeMethod(Class sender, Object object, String methodName, Object[] originalArguments, boolean isCallToSuper, boolean fromInsideClass)

您可以在第1044行(Groovy 2.4.12)找到它。 transform()类中不存在 String方法,因此Groovy必须在其他地方找到其实现。在这种情况下,该方法在第1055行中找到:
MetaMethod method = null;
if (CLOSURE_CALL_METHOD.equals(methodName) && object instanceof GeneratedClosure) {
method = getMethodWithCaching(sender, "doCall", arguments, isCallToSuper);
}

此方法最重要的部分是1283行:
if (!isCallToSuper && GroovyCategorySupport.hasCategoryInCurrentThread()) {
return getMethodWithoutCaching(sender, methodName, MetaClassHelper.convertToTypeArray(arguments), isCallToSuper);
} else {
....
}
GroovyCategorySupport.hasCategoryInCurrentThread()检查类别是否在当前线程中使用(在这种情况下使用 ThreadLocal)。

如果您跟踪接下来会发生什么,您将到达 MetaClassImpl所在的 getMethods(Class sender, String name, boolean isCallToSuper)行690。在706行中,此方法调用:
List used = GroovyCategorySupport.getCategoryMethods(name);

这是最后在类别类中按其名称实际找到该方法的最后一部分。稍后,它将检查该方法是否为静态方法,以及是否期望使用有效类型的参数(在这种情况下为 String)。

关于multithreading - Groovy类别的使用仅限于当前线程是什么意思?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49506598/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com