让并发线程将项目放入哈希映射中

问题描述 投票:0回答:1

我正在尝试拆分一个需要对多个线程进行多次迭代的循环,以提高速度性能。我的程序将循环分成 n 个间隔,其中 n 是线程数并同时运行它们。每当循环达到特定值时,它应该将信息存储到外部类中的 ConcurrentHashMap 中。

使用调试器时,我收到此通知:

((Worker)this).md4 = Inconvertible types; cannot cast 'org.example.hashes.Engine' to 'org.example.hashes.Engine.Worker'

public class Engine {
    private final ConcurrentHashMap<String, String> crackedPasswords = new ConcurrentHashMap<>();
    private final int NUM_THREADS;

    public Engine() {
        NUM_THREADS = numThreads;
    }

    public void runProcess() {
        ExecutorService executor = Executors.newFixedThreadPool(NUM_THREADS);
        for(int i=1; i<=NUM_THREADS; i++) {
            long workload = numCombs/NUM_THREADS;
            Worker worker = new Worker(workload * (i-1), workload*i);
            executor.execute(worker);
        }
        executor.shutdown();
   }

   public ConcurrentHashMap<String, String> getCrackedPasswords() {
        return crackedPasswords;
    }

   class Worker implements Runnable {
        private final MD4 md4 = new MD4();
        private final long iterationStart;
        private final long iterationEnd;

        public Worker(long inStart, long inEnd) {
            this.iterationStart = inStart;
            this.iterationEnd = inEnd;
        }

        @Override
        public void run() {
            for(long iteration=iterationStart; iteration<iterationEnd; iteration++) {
                checkHash(String.valueOf(currentPlain));
            }
        }

        private void checkHash(String plainText) {
            for(byte[] hashByte : hashBytes) {
                if (Arrays.equals(hashByte, md4.runDigest(plainText))){
                    StringBuilder hex = new StringBuilder(hashByte.length*2);
                    for(byte b: hashByte)
                        hex.append(String.format("%02x", b));

                    crackedPasswords.putIfAbsent(hex.toString(), plainText);
                }
            }
        }
    }
}

程序最终返回 null。当我不使用执行器创建一个线程并调用 run() 时,它会返回正确的值,但显然不是同时运行线程。

java multithreading concurrency
1个回答
0
投票

您需要等待并行工作完成才能退出应用程序。

这可以通过调用来完成

ExecutorService.awaitTermination(long, TimeUnit)
之后
ExecutorService.shutdown()

例如

ExecutorService executor = Executors.newFixedThreadPool(NUM_THREADS);
for (int i=1; i<=NUM_THREADS; i++) { 
   ... 
}
executor.shutdown();
boolean terminated = executor.awaitTermination(10, TimeUnit.MINUTES);   
if (!terminated) {
   throw new RuntimeException("Work not finished after waiting 10 minutes");
}  
© www.soinside.com 2019 - 2024. All rights reserved.