在这个项目中,Manager
执行事件排队,并返回事件的结果使用回调(回调不扩展Runnable
)。管理器在一个单独的线程上运行,调度事件。一旦事件终止,这个相同的线程就会调用回调。这意味着在前一个事件的回调终止之前,不会调度下一个事件。为了避免这种情况,我想让管理器为每个回调创建一个新线程,并在那里执行回调。这个解决方案在设计实践方面有多好,是否有更好的方法来实现这一目标?
答案 0 :(得分:5)
一个简单的Callback
代码:
import java.util.concurrent.*;
import java.util.*;
public class CallBackDemo{
public CallBackDemo(){
System.out.println("creating service");
ExecutorService service = Executors.newFixedThreadPool(10);
try{
for ( int i=0; i<10; i++){
Callback callback = new Callback(i+1);
MyCallable myCallable = new MyCallable((long)i+1,callback);
Future<Long> future = service.submit(myCallable);
//System.out.println("future status:"+future.get()+":"+future.isDone());
}
}catch(Exception err){
err.printStackTrace();
}
service.shutdown();
}
public static void main(String args[]){
CallBackDemo demo = new CallBackDemo();
}
}
class MyCallable implements Callable<Long>{
Long id = 0L;
Callback callback;
public MyCallable(Long val,Callback obj){
this.id = val;
this.callback = obj;
}
public Long call(){
//Add your business logic
System.out.println("Callable:"+id+":"+Thread.currentThread().getName());
callback.callbackMethod();
return id;
}
}
class Callback {
private int i;
public Callback(int i){
this.i = i;
}
public void callbackMethod(){
System.out.println("Call back:"+i);
// Add your business logic
}
}
输出:
creating service
Callable:1:pool-1-thread-1
Call back:1
Callable:2:pool-1-thread-2
Call back:2
Callable:8:pool-1-thread-8
Call back:8
Callable:3:pool-1-thread-3
Call back:3
Callable:10:pool-1-thread-10
Callable:4:pool-1-thread-4
Call back:10
Callable:7:pool-1-thread-7
Call back:7
Callable:6:pool-1-thread-6
Call back:6
Callable:9:pool-1-thread-9
Callable:5:pool-1-thread-5
Call back:9
Call back:4
Call back:5
要点:
Manager
替换为您首选的ExecutorService
。Callaback
对象传递给Callable/Runnable
对象或者您可以在Callback
内创建Callable/Runnable
对象。在我的示例中,我已将Callback
对象明确传递给Callable
。在返回结果之前,Callable
对象调用Callback
方法。如果你想阻止进一步继续进行,除非你得到当前事件的回应,只需在下面取消注释。
System.out.println("future status:"+future.get()+":"+future.isDone());
我认为你会避免它,因此保持高于评论。您不必为Callback
方法调用创建新线程。如果要异步处理Callback
事件,可以再创建一个ExecutorService
并提交事件。
答案 1 :(得分:2)
我会有执行任务的线程,也执行回调。我建议你不要每次创建一个Thread,而是使用ExecutorService。
public static <T> void submit(ExecutorService service,
Callable<T> callable,
Consumer<T> callback) {
service.submit(() -> {
try {
callback.accept(callable.call());
} catch (Throwable t) {
// log the Throwable
}
});
}