java concurrency使用Runnable与可调用和本地数据共享数据

时间:2016-06-03 10:20:12

标签: java multithreading concurrency thread-safety shared-data

第一种情况:假设你有很多任务都返回某种结果,现在就把它称为“结果”,这些都必须存储在一个arraylist中。有两种选择:

1)在main方法中创建一个arraylist,并使用runnables访问共享列表和同步的add方法

2)在main方法中创建一个arraylist并使用callable执行任务并返回结果,让main方法将Result添加到其列表中。

两者之间是否有任何性能差异,因为可运行需要同步访问,但是callables没有?

然后,到第二种情况:现在让我们说每个任务都会产生一个“小”的arraylist,比如每个任务少于10个项目。这又提供了两个选项:

1)main和runnable中的一个arraylist,可以访问共享列表,每次生成时都会添加结果项。

2)main和callables中的一个arrayList>每个他们自己的本地arraylist存储结果,直到任务完成,然后在main中使用addAll添加找到的结果。

与以前一样的问题,性能差异是什么?

为了清晰起见,在速度(某些同步问题等)和内存方面都表现出来(由于本地小型arraylist,callables是否使用了更多的内存,或者这个小到可以忽略不计)?

1 个答案:

答案 0 :(得分:0)

private static ExecutorService  exe = Executors.newCachedThreadPool();
private static List<Future<Result>> futureResults = new ArrayList<>();

public static void main(String[] args) throws ExecutionException, InterruptedException {
    Callable<Result> dummyTask = ()-> {
        System.out.println("Task is executed");
        Result dummyResult = new Result();
        return dummyResult;
    };

    //Submit a task
    submitTask(dummyTask);

    //Getting result of "0" index
    System.out.println(futureResults.get(0).get());
}

private static void submitTask(Callable<Result> task) {
    futureResults.add(exe.submit(task));
}

private static Result getResult(int taskNumber) throws ExecutionException, InterruptedException {
    return futureResults.get(taskNumber).get();
}
  1. 选项一:如果我们使用Runnable任务,那么我们就无法从run()方法返回任何内容。所以我认为这个选项不适合你的要求。

  2. 选项二:可调用 根据我对你的要求的理解,Callable是很好的候选人。 但是有一点变化,我们将创建一个Future列表,并且对于每个Callable任务(我们将提交给执行者)将把此Callable的Future结果(详见下面的代码)添加到此列表中。然后,只要我们需要任何任务的结果,我们就可以从相应的Future获得结果。

  3. 类MainTaskExecutor {

    class Result {
        // data to be added
    }
    

    }

    {{1}}