mirror of
https://gitee.com/dromara/hutool.git
synced 2025-07-17 01:46:22 +08:00
perf(core): 改用线程安全的方式从缓存中获取lambda对象
This commit is contained in:
parent
58d28c0767
commit
74db3733a2
@ -66,52 +66,49 @@ public class LambdaFactory {
|
|||||||
Assert.notNull(functionInterfaceType);
|
Assert.notNull(functionInterfaceType);
|
||||||
Assert.notNull(method);
|
Assert.notNull(method);
|
||||||
Tuple cacheKey = new Tuple(functionInterfaceType, method);
|
Tuple cacheKey = new Tuple(functionInterfaceType, method);
|
||||||
Object cacheValue = CACHE.get(cacheKey);
|
//noinspection unchecked
|
||||||
if (null != cacheValue) {
|
return (F) CACHE.computeIfAbsent(cacheKey, key -> {
|
||||||
//noinspection unchecked
|
List<Method> abstractMethods = Arrays.stream(functionInterfaceType.getMethods())
|
||||||
return (F) cacheValue;
|
.filter(m -> Modifier.isAbstract(m.getModifiers()))
|
||||||
}
|
.collect(Collectors.toList());
|
||||||
List<Method> abstractMethods = Arrays.stream(functionInterfaceType.getMethods())
|
Assert.equals(abstractMethods.size(), 1, "不支持非函数式接口");
|
||||||
.filter(m -> Modifier.isAbstract(m.getModifiers()))
|
if (!method.isAccessible()) {
|
||||||
.collect(Collectors.toList());
|
method.setAccessible(true);
|
||||||
Assert.equals(abstractMethods.size(), 1, "不支持非函数式接口");
|
}
|
||||||
if (!method.isAccessible()) {
|
Method invokeMethod = abstractMethods.get(0);
|
||||||
method.setAccessible(true);
|
MethodHandles.Lookup caller = LookupFactory.lookup(method.getDeclaringClass());
|
||||||
}
|
String invokeName = invokeMethod.getName();
|
||||||
Method invokeMethod = abstractMethods.get(0);
|
MethodType invokedType = methodType(functionInterfaceType);
|
||||||
MethodHandles.Lookup caller = LookupFactory.lookup(method.getDeclaringClass());
|
MethodType samMethodType = methodType(invokeMethod.getReturnType(), invokeMethod.getParameterTypes());
|
||||||
String invokeName = invokeMethod.getName();
|
MethodHandle implMethod = Opt.ofTry(() -> caller.unreflect(method)).get();
|
||||||
MethodType invokedType = methodType(functionInterfaceType);
|
MethodType insMethodType = methodType(method.getReturnType(), method.getDeclaringClass(), method.getParameterTypes());
|
||||||
MethodType samMethodType = methodType(invokeMethod.getReturnType(), invokeMethod.getParameterTypes());
|
boolean isSerializable = Arrays.stream(functionInterfaceType.getInterfaces()).anyMatch(i -> i.isAssignableFrom(Serializable.class));
|
||||||
MethodHandle implMethod = Opt.ofTry(() -> caller.unreflect(method)).get();
|
CallSite callSite = Opt.ofTry(() -> isSerializable ?
|
||||||
MethodType insMethodType = methodType(method.getReturnType(), method.getDeclaringClass(), method.getParameterTypes());
|
LambdaMetafactory.altMetafactory(
|
||||||
boolean isSerializable = Arrays.stream(functionInterfaceType.getInterfaces()).anyMatch(i -> i.isAssignableFrom(Serializable.class));
|
caller,
|
||||||
CallSite callSite = Opt.ofTry(() -> isSerializable ?
|
invokeName,
|
||||||
LambdaMetafactory.altMetafactory(
|
invokedType,
|
||||||
caller,
|
samMethodType,
|
||||||
invokeName,
|
implMethod,
|
||||||
invokedType,
|
insMethodType,
|
||||||
samMethodType,
|
FLAG_SERIALIZABLE
|
||||||
implMethod,
|
) :
|
||||||
insMethodType,
|
LambdaMetafactory.metafactory(
|
||||||
FLAG_SERIALIZABLE
|
caller,
|
||||||
) :
|
invokeName,
|
||||||
LambdaMetafactory.metafactory(
|
invokedType,
|
||||||
caller,
|
samMethodType,
|
||||||
invokeName,
|
implMethod,
|
||||||
invokedType,
|
insMethodType
|
||||||
samMethodType,
|
)).get();
|
||||||
implMethod,
|
|
||||||
insMethodType
|
try {
|
||||||
)).get();
|
//noinspection unchecked
|
||||||
|
return (F) callSite.getTarget().invoke();
|
||||||
|
} catch (Throwable e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
try {
|
|
||||||
//noinspection unchecked
|
|
||||||
F lambda = (F) callSite.getTarget().invoke();
|
|
||||||
CACHE.put(cacheKey, lambda);
|
|
||||||
return lambda;
|
|
||||||
} catch (Throwable e) {
|
|
||||||
throw new RuntimeException(e);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user