【发布时间】:2018-08-23 01:43:35
【问题描述】:
所以我试图从磁盘中删除 listDir 中列出的 n 个文件,因此我将 listDir 分为 4 个部分,并让它从磁盘中并行删除。这里的目的是并行执行,以使其快速而不是顺序执行。 deleteObject(x,credential,token) 可以假设为一个 API,它最终从磁盘中删除一个对象,并且是一个原子操作。删除成功返回true,否则返回false
我这里有几个问题
- 所以我有 4 个并行方法,我正在通过 invokeAll 执行 Executors.newFixedThreadPool(4) 声明了 4 个线程 是否总是将 1 个线程分配给 1 个方法?
- 是否需要在 parallelDeleteOperation() 方法的 for 循环中同步和使用 volatile 迭代器“i”。我问这个的原因是假设第一个线程没有完成它的任务(删除 listDir1 并且 for 循环没有完成)并且假设在中途它得到了上下文切换并且第二个线程开始执行相同的任务(删除 listDir1)。只是想知道在这种情况下,第二个线程是否可以获得 IndexOutOfBound 异常。
- 将列表分成 4 部分并执行此操作,而不是让多个线程在一个非常大的列表上执行删除操作有什么好处。
-
如果 ExecutorService 的其中一项操作返回 false,那么整个 deleteMain() API 将返回 false
private boolean deleteMain(String parent, List<Structure> listDir, String place, String node, Sequence<String> groups, String Uid) throws IOException { int noCores = Runtime.getRuntime().availableProcessors(); List<List<Integer>> splittedList = splitList(listDir, noCores); System.out.println(splittedList.size()); System.out.println("NoOfCores" + noCores); Set<Callable<Boolean>> callables = new HashSet<Callable<Boolean>>(); for (int i = 0; i < splittedList.size(); i++) { List<Integer> l = splittedList.get(i); callables.add(new Callable<Boolean>() { @Override public Boolean call() throws Exception { return parallelDeleteOperation(parent, listDir, place, node, groups Uid); } }); } ExecutorService service = Executors.newFixedThreadPool(noCores); try { List<Future<Boolean>> futures = service.invokeAll(callables); for (Future<Boolean> future : futures) { if (future.get() != true) return future.get(); } } catch (InterruptedException e) { e.printStackTrace(); } catch (ExecutionException e) { e.printStackTrace(); } service.shutdown(); return true; } private Boolean parallelDeleteOperation(String parent, List<Structure> listDir, String place, String node, Sequence<String> groups, String Uid) throws IOException { for (int i = 0; i < listDir.size(); i++) { final String name = listDir.get(i).filename; final String filePath = "/" + (parent.isEmpty() ? "" : (parent + "/")) + name; final DeleteMessage message = new DeleteMessage(name, place, node filePath); final boolean Status = delete(message, groups, Uid, place); if (Status != true) return Status; } return true; }
【问题讨论】:
-
用
listDir.parallelStream().forEach(this::deleteObject);替换整个东西。 -
稍微修改了deleteObject代码。
标签: java multithreading future executorservice callable