I am new to threads topic. I need to submit tasks to the executor service asynchronously and also need to get the responses back. I have tried to examples like below.
Case 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)
Case 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)
My question is why I am seeing different results in above two cases. If I don't declare i as global variable I am getting below error.
Local variable i defined in an enclosing scope must be final or effectively final
Mostly because of this I am getting unexpected output, since other thread could have modified the value of I by the time slave prints it ? In real time Task class is a more complex object (which has logics to get data from services and write the same to DB) and how would I take care of this if Task class is not implements Callable ?
Is it mandatory that the instance/task which I am submitting to executor need to implement Callable (for this I need to ask the owner of the task class to explicitly implement Callable).
Or creating anonymous class in runtime and adding the instantiating task class inside call() is also correct way to do ?