我有一個代碼,它有兩個執行程序,executorShops
和executorSections
,但第一個並不重要。線程排隊時沒有更新共享列表
我創建了與部分一樣多的任務(本例中爲三個),但是,只有兩個部分同時執行。
每個任務都會更新一個共享列表,但問題只是前兩個線程正確更新它。已經排隊的第三個線程不會更新它。
下面是其中任務是創建的代碼:
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,那麼第二和第三個線程不會更新列表。
有誰知道我做錯了什麼?
在此先感謝,
你介意嘗試爲[synchronizedList]交換CopyOnWriteArraylist(https://docs.oracle.com/javase/8/docs/api/java/util/Collections.html#synchronizedList-java.util.List- ) - 包裝ArrayList? – Fildor
我會盡快嘗試。 – cuoka
http://stackoverflow.com/questions/17853112/in-what-situations-is-the-copyonwritearraylist-suitable – Antoniossss