为什么我的多线程任务不能正常工作?

时间:2015-07-29 15:07:07

标签: java multithreading collections

我正在尝试使用批处理操作从facebook获取帖子。 我想让这个任务多线程以加快操作。 基本上,我发送批处理请求到Facebook,并在等待响应时,我的任务是做其他需要完成的事情。 当我调试任务(慢慢地)我得到了2000个结果我想得到测试.... 但是当我运行它或让它在请求操作之后进行调试和暂停时,它会小于2000。

    String[] str = new String[2000];
    ExecutorService exec = Executors.newFixedThreadPool(10);
    List<BatchRequest> request= new CopyOnWriteArrayList<BatchRequest>();
    List <BatchResponse> batchResponses = new ArrayList<BatchResponse>();



    int i=1;
    for(int j=0 ; j<2000; j++) {

        if (i < 50) {
            BatchRequest batch = new BatchRequestBuilder(str[i]).build();
            request.add(batch);
            i++;
            counter++;
        } else {
            i = 1;
            exec.execute(new Runnable() {

                //thread that gets information from facebook into a list of responses
                public void run() {
                    // TODO Auto-generated method stub
                    System.out.println("running");
                    batchResponses.addAll(fc.executeBatch(request));
                    System.out.println("done");

                }

            });
            request.clear();
        }
    }
    exec.shutdown();
    exec.awaitTermination(Long.MAX_VALUE, TimeUnit.NANOSECONDS);

我删除了所有不必要的内容。希望它仍然有意义。

我的代码有什么问题?

编辑:我编辑了代码以使其更有意义。任何人吗?

3 个答案:

答案 0 :(得分:1)

除了@OldCurmudgeon的回答,我可以说ArrayList不是线程安全的类。您可以使用其他容器,使用Collections.synchronizedList()包装它或将同步添加到您的代码中。

还要确保您的fc变量引用线程安全类。

答案 1 :(得分:0)

您的代码似乎在counteri之间存在一些混淆。也许如果你解释为什么你需要这些东西会变得更清楚。

代码代表的主要问题是你永远不会将counter设置为零。这将导致前500个在其自己的线程中作为一个批处理执行,但其余的每个都将自行执行。

答案 2 :(得分:0)

一些问题: batchResponses正在线程内部访问,并且您正在主线程中推送它。 batchResponses也不是线程安全的,因此需要同步它。

你也在主线程中做request.clear ...这是bug,因为你不能保证新线程已执行,可能是新线程清除后运行的情况。新线程将看到request.size(0)= 0。

主if块和else块具有相同的线程代码,这有点令人困惑。 if(i == 50)你进入else块并执行请求。 当你的计数器是500时,你已经访问了else块10次,所以你可能有空的请求或你插入的最后50个。

此代码中的某些内容尚不清楚。