提交,实现Callable的类和不执行服务的类

时间:2016-06-11 15:40:19

标签: java multithreading threadpool executorservice callable

我是线程话题的新手。我需要异步地向执行程序服务提交任务,还需要获取响应。我试过以下的例子。

案例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声明为全局变量,那么我将低于错误。

  

我在封闭范围内定义的局部变量必须是最终的或有效的最终

主要是因为这个我得到了意想不到的输出,因为其他线程可能在奴隶打印时修改了I的值?实时Task类是一个更复杂的对象(它具有从服务获取数据并将其写入DB的逻辑),如果Task类没有实现Callable,我将如何处理这个?

我提交给执行者的实例/任务是否必须实现Callable(为此我需要请求任务类的所有者明确实现Callable)。

或者在运行时创建匿名类并在call()中添加实例化任务类也是正确的方法吗?

1 个答案:

答案 0 :(得分:0)

如果我理解你的问题:你可以使用lambdas或方法引用,而那些不必显式实现Callable。只需要遵循相同的约定:返回一些东西(不是void,就像Runnable一样)并且能够抛出异常。 (但这只适用于Java 8+!)