-1

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 ?

Babulu
  • 334
  • 4
  • 16
  • I am not passing something else to submit, I have clearly declared Callable anonymous class inside for loop. My code will compile and I have mentioned that error only if don't declare the i as a global variable. – Babulu Jun 11 '16 at 16:26
  • OK. First snippet: Task implements Callable, but doesn't override call(). So it can't compile. Uses Executor.newCachedTheadPool(), which doesn't exist. Second snippet: calls an unexisting method syso. Third snippet: uses an undefined variable named `int`. Can't possibly compile. Tries to use a non-final variable from an anonymous class. Can't compile. – JB Nizet Jun 11 '16 at 16:29
  • Please try to get the context of the question and try to answer my question. I havn't copy pasted my actual code here (so it is just int not object)...and used syso as short cut for System.out.println. Yes agree that I missed to override call in first place. I have added now. – Babulu Jun 11 '16 at 16:35
  • You can't access instance variable `i` form static method `main`. I has to be static. – subhash kumar singh Jun 11 '16 at 21:03
  • Re, "I havn't copy pasted my actual code," Well, you came here because there's something about your code that you don't understand. So how can you be certain that you didn't leave out the important part? The best questions contain a sample of code that other people can actually compile and run, and which does something different from what you were expecting it to do. – Solomon Slow Jun 12 '16 at 21:41

1 Answers1

0

If I understood your question correctly: You can use lambdas or method references and those do not have to implement Callable explicitly. The just have to follow the same conventions: return something (not void, like Runnable would) and be able to throw an Exception. (That would only work in Java 8+, though!)

Silverclaw
  • 1,316
  • 2
  • 15
  • 28
  • I want to submit the tasks which are not callable to executorservice by making use of anonymous inner class as I have written in case 2. But I see by doing that I get different output compared to the task which implement callable. I am asking this because if submitting tasks through case 2 is not advised then I will mandate the implementor of the Task class to implement the Callable than leaving it to me (task scheduler) – Babulu Jun 11 '16 at 16:42
  • And I'm telling you, you might not need an anonymous class at all: Executors.newCachedThreadPool().submit(SomeClass::doesNotImplementCallable); works fine, as long as it returns something and can throw an exception. – Silverclaw Jun 11 '16 at 16:52
  • Thank you.. will chk this and accept as answer if it works. – Babulu Jun 11 '16 at 17:18