【发布时间】:2016-10-12 10:37:47
【问题描述】:
我是线程主题的新手。我需要将任务异步提交给执行器服务,并且还需要取回响应。我尝试过以下示例。
案例一:
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 声明为全局变量,我将遇到错误。
我在封闭范围内定义的局部变量必须是最终的或有效的最终
主要是因为这个,我得到了意外的输出,因为其他线程可能在奴隶打印它时修改了 I 的值?实时任务类是一个更复杂的对象(它具有从服务获取数据并将其写入数据库的逻辑),如果任务类没有实现 Callable,我将如何处理?
我提交给执行者的实例/任务是否必须实现 Callable(为此我需要要求任务类的所有者明确实现 Callable)。
或者在运行时创建匿名类并在 call() 中添加实例化任务类也是正确的做法?
【问题讨论】:
-
我没有传递其他东西来提交,我已经在 for 循环中明确声明了 Callable 匿名类。我的代码将编译,并且仅在不将 i 声明为全局变量时才提到该错误。
-
好的。第一个 sn-p:Task 实现了 Callable,但没有覆盖 call()。所以无法编译。使用不存在的 Executor.newCachedTheadPool()。第二个sn-p:调用一个不存在的方法syso。第三个 sn-p:使用名为
int的未定义变量。不可能编译。尝试使用来自匿名类的非最终变量。无法编译。 -
请尝试获取问题的上下文并尝试回答我的问题。我没有在这里复制粘贴我的实际代码(所以它只是 int 不是对象)......并使用 syso 作为 System.out.println 的快捷方式。是的,同意我首先错过了覆盖电话。我已经添加了。
-
您无法通过静态方法
main访问实例变量i。我必须是静态的。 -
Re,“我没有复制粘贴我的实际代码,”好吧,您来到这里是因为您的代码有些地方您不理解。那么你怎么能确定你没有遗漏重要的部分呢?最好的问题包含一个其他人可以实际编译和运行的代码示例,它的作用与您期望的不同。
标签: java multithreading threadpool executorservice callable