作者热门文章
- Java 双重比较
- java - 比较器与 Apache BeanComparator
- Objective-C 完成 block 导致额外的方法调用?
- database - RESTful URI 是否应该公开数据库主键?
我有N个大文件(不少于250M)要散列。这些文件在 P 物理驱动器上。
我想用最多 K 个 Activity 线程同时对它们进行哈希处理,但我不能对每个物理驱动器进行超过 M 个文件的哈希处理,因为它会减慢整个过程(我运行了一个测试,解析 61 个文件,并使用 8 个线程比 1 个线程慢;文件几乎都在同一个磁盘上)。
我想知道最好的方法是什么:
我的代码是:
int K = 8;
int M = 1;
Queue<Path> queue = null; // get the files to hash
final ExecutorService newFixedThreadPool = Executors.newFixedThreadPool(K);
final ConcurrentMap<FileStore, Integer> counter = new ConcurrentHashMap<>();
final ConcurrentMap<FileStore, Integer> maxCounter = new ConcurrentHashMap<>();
for (FileStore store : FileSystems.getDefault().getFileStores()) {
counter.put(store, 0);
maxCounter.put(store, M);
}
List<Future<Result>> result = new ArrayList<>();
while (!queue.isEmpty()) {
final Path current = queue.poll();
final FileStore store = Files.getFileStore(current);
if (counter.get(store) < maxCounter.get(store)) {
result.add(newFixedThreadPool.submit(new Callable<Result>() {
@Override
public Entry<Path, String> call() throws Exception {
counter.put(store, counter.get(store) + 1);
String hash = null; // Hash the file
counter.put(store, counter.get(store) - 1);
return new Result(path, hash);
}
}));
} else queue.offer(current);
}
抛开潜在的非线程安全操作(比如我如何使用计数器),是否有更好的方法来实现我的目标?
我也认为这里的循环可能有点太多了,因为它可能会占用很多进程(几乎像一个无限循环)。
最佳答案
如果驱动器硬件配置在编译时未知,并且可能会被更改/升级,则很有可能为每个驱动器使用线程池并使线程数可由用户配置。我不熟悉“newFixedThreadPool”——线程计数是一个可以在运行时更改以优化性能的属性吗?
关于java - 使用线程同时散列(sha1)多个文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8020187/
我是一名优秀的程序员,十分优秀!