线程排队时未更新共享列表

时间:2016-10-17 07:18:56

标签: java multithreading executorservice

我有一个代码,它有两个执行器,executorShopsexecutorSections,但第一个并不重要。

我创建了与部分一样多的任务(本例中为三个),但是,只有两个同时执行。

每个任务都会更新共享列表,但问题是只有前两个线程才能正确更新它。排队的第三个线程不会更新它。

这是创建任务的代码:

Runnable task = () -> {
    LOG.info("Llamamos al ScraperManager para obtener el scraper de " + shop.getName());
    Scraper scraper = ScraperManager.getScraper(shop);
    LOG.info("Scraper de " + shop.getName() + " obtenido");

    ExecutorService executorSections = Executors.newFixedThreadPool(Properties.MAX_THREADS_SECTIONS);
    Set<Callable<List<Product>>> listOfTasks = new HashSet<>();    

    for (int j = 0; j < shop.getSections().size(); j++)
    {
        final Section section = shop.getSections().get(j);

        Callable<List<Product>> taskSection = () -> scraper.scrap(shop, section);

        listOfTasks.add(taskSection);                    
    }

    try 
    {
        List<Future<List<Product>>> listOfFutures = executorSections.invokeAll(listOfTasks);
        List<Product> productList = listOfFutures.get(shop.getSections().size() - 1).get();

        RestClient restClient = new RestClient(new URL(Properties.SERVER));

        restClient.saveProducts(productList, shop);

        countDownLatch.countDown();

        executorSections.shutdown();

    } catch (InterruptedException | ExecutionException ex ) {
        ...

    } catch (MalformedURLException ex) {
        ...
    }
};

这是废料任务:

public class ShopScraper implements Scraper
{
    private static List<Product> productList = Collections.synchronizedList(new ArrayList<>());

    private static final ThreadLocal<Boolean> threadFinished = 
            new ThreadLocal<Boolean>() 
            {
                @Override 
                protected Boolean initialValue() 
                {
                    return false;
                }
            };

    @Override
    public List<Product> scrap(Shop shop, Section section) throws IOException
    {
        // add products to the list

        return productList;
    }
}

编辑:如果我将线程数限制为1,则第二个和第三个线程不会更新列表。

有谁知道我做错了什么?

提前致谢,

1 个答案:

答案 0 :(得分:0)

当时1个线程= 1个任务。

    // MAX_THREADS_SECTIONS = 2
    ExecutorService executorSections = Executors.newFixedThreadPool(Properties.MAX_THREADS_SECTIONS);

将池大小限制为仅2个线程,因此只会并行运行2个任务。

增加它,所有任务将同时运行。