2016-10-17 66 views
1

我有一個代碼,它有兩個執行程序,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,那麼第二和第三個線程不會更新列表。

有誰知道我做錯了什麼?

在此先感謝,

+0

你介意嘗試爲[synchronizedList]交換CopyOnWriteArraylist(https://docs.oracle.com/javase/8/docs/api/java/util/Collections.html#synchronizedList-java.util.List- ) - 包裝ArrayList? – Fildor

+0

我會盡快嘗試。 – cuoka

+0

http://stackoverflow.com/questions/17853112/in-what-situations-is-the-copyonwritearraylist-suitable – Antoniossss

回答

0

1線程= 1時的任務。

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

您是限制你的池大小隻有2個線程,所以只有2個任務將並行運行。

增加並且所有任務將在同一時間運行。

+0

是的,我知道,但我需要限制並行運行的線程數。 – cuoka

+0

@cuoka限制解釋了爲什麼2個任務運行保證爲3。然而,第三個任務應該在前2個任務之一完成之後運行,因此結論是 - 提供的任務永遠不會結束。你必須展示'ShopScraper#scrap'的功能,因爲那裏很可能存在僵局。 – Antoniossss

+0

執行三個任務,前兩個並行,第三個任務完成後,每個線程完成,因爲「if(hasEveryoneFinished(finishedSections))」中的塊被執行。我的問題是,第三個線程不會更新列表,當前兩個做。 – cuoka

相關問題