Source:
void write(final ReplicationSpec forReplicationSpec) throws InterruptedException, HiveException { ExecutorService producer = Executors.newFixedThreadPool(1, new ThreadFactoryBuilder().setNameFormat("partition-submitter-thread-%d").build()); producer.submit(() -> { SessionState.setCurrentSessionState(callersSession); for (Partition partition : partitionIterable) { try { queue.put(partition); } catch (InterruptedException e) { throw new RuntimeException( "Error while queuing up the partitions for export of data files", e); } } }); producer.shutdown(); ThreadFactory namingThreadFactory = new ThreadFactoryBuilder().setNameFormat("partition-dump-thread-%d").build(); ExecutorService consumer = Executors.newFixedThreadPool(nThreads, namingThreadFactory); List<Future<?>> futures = new LinkedList<>(); while (!producer.isTerminated() || !queue.isEmpty()) { Partition partition = queue.poll(1, TimeUnit.SECONDS); if (partition == null) { continue; } LOG.debug("scheduling partition dump {}", partition.getName()); futures.add(consumer.submit(() -> { String partitionName = partition.getName(); String threadName = Thread.currentThread().getName(); LOG.debug("Thread: {}, start partition dump {}", threadName, partitionName); try { List<Path> dataPathList = Utils.getDataPathList(partition.getDataLocation(), forReplicationSpec, hiveConf); Path rootDataDumpDir = paths.partitionExportDir(partitionName); new FileOperations(dataPathList, rootDataDumpDir, distCpDoAsUser, hiveConf, mmCtx) .export(forReplicationSpec); LOG.debug("Thread: {}, finish partition dump {}", threadName, partitionName); } catch (Exception e) { throw new RuntimeException(e.getMessage(), e); } })); } consumer.shutdown(); for (Future<?> future : futures) { try { future.get(); } catch (Exception e) { LOG.error("failed", e.getCause()); throw new HiveException(e.getCause().getMessage(), e.getCause()); } } consumer.awaitTermination(Long.MAX_VALUE, TimeUnit.SECONDS); }

Target:
void write(final ReplicationSpec forReplicationSpec) throws InterruptedException, HiveException { List<Future<?>> futures = new LinkedList<>(); ExecutorService producer = Executors.newFixedThreadPool(1, new ThreadFactoryBuilder().setNameFormat("partition-submitter-thread-%d").build()); futures.add(producer.submit(() -> { SessionState.setCurrentSessionState(callersSession); for (Partition partition : partitionIterable) { try { queue.put(partition); } catch (InterruptedException e) { throw new RuntimeException( "Error while queuing up the partitions for export of data files", e); } } })); producer.shutdown(); ThreadFactory namingThreadFactory = new ThreadFactoryBuilder().setNameFormat("partition-dump-thread-%d").build(); ExecutorService consumer = Executors.newFixedThreadPool(nThreads, namingThreadFactory); while (!producer.isTerminated() || !queue.isEmpty()) { Partition partition = queue.poll(1, TimeUnit.SECONDS); if (partition == null) { continue; } LOG.debug("scheduling partition dump {}", partition.getName()); futures.add(consumer.submit(() -> { String partitionName = partition.getName(); String threadName = Thread.currentThread().getName(); LOG.debug("Thread: {}, start partition dump {}", threadName, partitionName); try { List<Path> dataPathList = Utils.getDataPathList(partition.getDataLocation(), forReplicationSpec, hiveConf); Path rootDataDumpDir = paths.partitionExportDir(partitionName); new FileOperations(dataPathList, rootDataDumpDir, distCpDoAsUser, hiveConf, mmCtx) .export(forReplicationSpec); LOG.debug("Thread: {}, finish partition dump {}", threadName, partitionName); } catch (Exception e) { throw new RuntimeException(e.getMessage(), e); } })); } consumer.shutdown(); for (Future<?> future : futures) { try { future.get(); } catch (Exception e) { LOG.error("failed", e.getCause()); throw new HiveException(e.getCause().getMessage(), e.getCause()); } } consumer.awaitTermination(Long.MAX_VALUE, TimeUnit.SECONDS); }