如何在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