如何在Java中包装多个方法?枚举不是';这条路不对吗?
我有一个名为如何在Java中包装多个方法?枚举不是';这条路不对吗?,java,concurrency,enums,word-wrap,Java,Concurrency,Enums,Word Wrap,我有一个名为A的接口,需要在程序启动后由类I动态加载来实现。我们把它叫做B 此接口提供x个(多于1个)方法。让我们从a()调用em到z()。 现在我必须将这个类包装一段时间来度量和控制问题,并在它自己的线程中运行它,以便在需要太长时间的情况下杀死它 因此,我发明了类C,它包装B,因为B本身并不实现runnable 下一部分是原始程序应该调用的类。新类DD实现接口A以及对模型隐藏整个控制部分 现在我必须将接口的方法包装在D中,并将它们发送给C,C将其展开并在对象B上执行它们 下面是一些我想象中的示
A
的接口,需要在程序启动后由类I动态加载来实现。我们把它叫做B
此接口提供x个(多于1个)方法。让我们从a()
调用em到z()
。
现在我必须将这个类包装一段时间来度量和控制问题,并在它自己的线程中运行它,以便在需要太长时间的情况下杀死它
因此,我发明了类C
,它包装B
,因为B
本身并不实现runnable
下一部分是原始程序应该调用的类。新类D
D
实现接口A
以及对模型隐藏整个控制部分
现在我必须将接口的方法包装在D中,并将它们发送给C,C将其展开并在对象B上执行它们
下面是一些我想象中的示例代码:
public class D implements A {
private C ai;
public D(String aiName) {
ai = new C("trivialKi");
}
private void call(parameters, ORIGIN_METHOD origin) {
AiTaskExecutor task = new AiTaskExecutor(parameters, origin, ai);
FutureTask<Long> tsk = new FutureTask<Long>(task);
Thread thread = new Thread(tsk);
thread.start();
if (abort) {
tsk.cancel(true);
}
}
@Override
public void a(g g, f f, t t) {
call(g, f, t, ORIGIN_METHOD.a);
}
@Override
public void b(g g, t t, h h) {
call(g, t, h, ORIGIN_METHOD.b);
}
@Override
public void c(g g, t t, f f) {
call(g, t, f, ORIGIN_METHOD.c);
}
}
公共类D实现了{
私人人工智能;
公共D(字符串名称){
ai=新的C(“Ki”);
}
私有void调用(参数、原点\方法原点){
AiTaskExecutor任务=新的AiTaskExecutor(参数、原点、ai);
FutureTask tsk=新的FutureTask(任务);
螺纹=新螺纹(tsk);
thread.start();
如果(中止){
tsk.取消(真);
}
}
@凌驾
公共无效a(g、f、t){
调用(g,f,t,ORIGIN_METHOD.a);
}
@凌驾
公共空间b(g、t、h){
调用(g,t,h,ORIGIN_METHOD.b);
}
@凌驾
公共空间c(g、t、f){
调用(g,t,f,ORIGIN_METHOD.c);
}
}
在类C中,使用枚举将参数传递给类B上的正确方法是一种明显的切换情况,该方法保存在类C的als私有字段中
你有更好的解决办法吗?
我个人不喜欢enum,如果参数太不一样,这就不能很好地工作
这类事情有“标准”解决方案吗?这方面的标准解决方案是:对a使用“动态代理”(
java.lang.reflect.Proxy
),这样可以节省几乎所有的样板代码
本网站和谷歌提供了足够多的代理使用示例
另外:我建议不要为每次调用使用新线程——如果调用的方法很短,那么这将非常昂贵。您可以改用Callable
接口Runnable
和线程池Executor
。这还允许您在接口中具有返回值:-)
编辑
只是为了好玩,我编写了动态代理和执行器的代码
给定以下接口A
和示例实现B
:
interface A {
int a(int g, int f, int h);
int b(int x);
}
class B implements A {
@Override
public int a(int g, int f, int t) {
System.out.println("called a in thread "+Thread.currentThread().getName());
return 42;
}
@Override
public int b(int x) {
System.out.println("called b in thread "+Thread.currentThread().getName());
return 21;
}
}
使用反射调用任何java.lang.reflect.Method
的适当Callable
如下所示:
class ReflectiveMethodCallable implements Callable<Object> {
private Object target;
private Method method;
private Object[] args;
public ReflectiveMethodCallable(Object target, Method method, Object[] args) {
this.target = target;
this.method = method;
this.args = args;
}
@Override
public Object call() throws Exception {
return method.invoke(target, args);
}
}
在createProxyFor
中创建新的Proxy
时使用InvocationHandler
。Main
类的其余部分用于SSCCE示例:
public class Main {
public static void main(String[] args) throws InterruptedException {
ExecutorService executorService = Executors.newCachedThreadPool();
// get B somehow
A a = new B();
// get proxy for B
A proxy = createProxyFor(a, executorService);
// call proxy
System.out.println("current thread: "+Thread.currentThread().getName());
int resultA = proxy.a(1,2,3);
System.out.println("calling a returned "+resultA);
int resultB = proxy.b(1);
System.out.println("calling b returned "+resultB);
}
static A createProxyFor(A a, ExecutorService executorService){
InvocationHandler h = new MyInvocationHandler(a, executorService);
A proxy = (A)Proxy.newProxyInstance(A.class.getClassLoader(), new Class[]{A.class}, h);
return proxy;
}
}
输出:
current thread: main
called a in thread pool-1-thread-1
calling a returned 42
called b in thread pool-1-thread-1
calling b returned 21
最后:
A
中的每个方法都将在另一个线程中调用
- 线程池重用线程李>
- 附加逻辑(例如时间测量、超时控制)可以在
invoke
或call
中完成
- 不需要为每个方法编写任何代码
您的描述和提供的代码中都没有枚举。我不明白你的问题。请尽量给出最简单的例子,用有意义的名字代替A、B、C、D等。这就是我想要的。非常感谢你的详细解释
current thread: main
called a in thread pool-1-thread-1
calling a returned 42
called b in thread pool-1-thread-1
calling b returned 21