我的代码有两个执行器,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,则第二个和第三个线程不会更新列表。
有人知道我做错了什么吗?
提前致谢,
最佳答案
当时 1 个线程 = 1 个任务。
// MAX_THREADS_SECTIONS = 2
ExecutorService executorSections = Executors.newFixedThreadPool(Properties.MAX_THREADS_SECTIONS);
您将池大小限制为仅 2 个线程,因此只有 2 个任务将并行运行。
增加该值,所有任务将同时运行。
关于java - 线程排队时共享列表未更新,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40080523/