java将实现可调用的类和不实现可调用的类提交给executor服务时有什么区别
我不熟悉这个话题。我需要异步地将任务提交给executor服务,还需要获取响应。我尝试过下面的例子
案例1:
public class Task implements Callable<Integer> {
Integer i;
public Task(Integer i){
this.i = i;
}
@Override
public Integer call(){
doTask();
}
public Integer doTask(){
syso(i);
return i;
}
}
public class ExecuteTask(){
public void static main (String [] args){
ExecutorService service = Executor.newCachedTheadPool();
for(int i = 0; int <10; i++) {
service.sumbit(new Task(i).doTask());
}
}
}
Output: 0,1,2,3,4,7,9,5,8,6 (expected)
案例2:
public class Task {
Integer i;
public Task(Integer i){
this.i = i;
}
public Integer doTask(){
syso(i);
return i;
}
}
public class ExecuteTask(){
int i;
public void static main (String [] args){
ExecutorService service = Executor.newCachedTheadPool();
for(i = 0; int <10; i++) {
service.sumbit(new Callable<Integer>(){
@Override
public Integer call() {
Integer int = new Task(i).doTask();
return int;
}
});
}
}
}
Output: 1,3,3,6,6,6,10,10,10,10 (not expected)
我的问题是,为什么我在上述两种情况下看到不同的结果。若我不将I声明为全局变量,那个么我将得到下面的错误
Local variable i defined in an enclosing scope must be final or effectively final
主要是因为这个原因,我得到了意外的输出,因为在slave打印I时,其他线程可能已经修改了I的值?实时任务类是一个更复杂的对象(它具有从服务获取数据并将数据写入数据库的逻辑),如果任务类不可调用,我将如何处理这个问题
我提交给executor的实例/任务必须实现Callable(为此,我需要要求任务类的所有者显式实现Callable)
或者在运行时创建匿名类并在call()中添加实例化任务类也是正确的方法
# 1 楼答案
如果我正确理解了您的问题:您可以使用lambda或方法引用,而不必显式实现Callable。用户只需遵循相同的约定:返回某些内容(而不是像Runnable那样的void)并能够抛出异常。 (不过,这只适用于Java8+)