Java 改进ExecutorService以在超过1个cpu上执行进程

Java 改进ExecutorService以在超过1个cpu上执行进程,java,multithreading,cpu-usage,future,executorservice,Java,Multithreading,Cpu Usage,Future,Executorservice,当我运行下面的代码时,javaw.exe似乎只使用了一个核心 int cores = Runtime.getRuntime().availableProcessors(); System.out.println("Number of cores: " + cores); //8 cores int partitionSize = alphabet.length / cores; ExecutorService service = Executors.newFixedThreadPool(cor

当我运行下面的代码时,javaw.exe似乎只使用了一个核心

int cores = Runtime.getRuntime().availableProcessors();
System.out.println("Number of cores: " + cores); //8 cores

int partitionSize = alphabet.length / cores;
ExecutorService service = Executors.newFixedThreadPool(cores);
List<Future> futures = new ArrayList<Future>();

for (int c = 0; c < cores; c++) {

    char[] part = Arrays.copyOfRange(alphabet, c * partitionSize, (c + 1) * partitionSize);
    futures.add(service.submit(new BruteWorker(part) ));

}

for(Future f : futures)
    f.get();

为什么其他线程什么都不做

布鲁特沃克职业:

public class BruteWorker implements Runnable {
    private static final char[] alphabet = "eaistnrulodmpcvqgbfjhzxykw0123456789!@#$%&*".toCharArray();
    private static final int maxLength = 8;
    private static Map<String, String> hashes;
    private static MessageDigest md ;
    private char[] partition;
    private long nbTries = 0;

    BruteWorker(char[] partition, Map<String, String> hashes) {
        this.partition = partition;
        this.hashes = hashes;
    }

    public void run() {
        System.out.println("New thread (id = "+ Thread.currentThread().getId() +")");
        try {
            md = MessageDigest.getInstance("MD5");
            for(char c : this.partition){
                stringPossibilities(String.valueOf(c), maxLength);
            }
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        }
        System.out.println("End of thread (id = "+ Thread.currentThread().getId() +")");
    }

    //Recursive class
    private void stringPossibilities(String prefix, int length) {
        nbTries++;
        if((nbTries % 10000000) == 0){
            System.out.println(nbTries + " tries on thread id = "+ Thread.currentThread().getId());
        }
        md.update(prefix.getBytes());
        byte[] bytes = md.digest();
        String md5 = getMd5Hash(prefix);

        if (hashes.containsKey(md5)){
            System.out.println(prefix + " = " + md5);
        }


        if (prefix.length() < length){
            for (int i = 0; i < alphabet.length; i++){
                char c = alphabet[i];
                stringPossibilities(prefix + c, length);
            }
        }
    }

    private String getMd5Hash(String prefix){
        md.update(prefix.getBytes());
        byte[] bytes = md.digest();
        StringBuilder md5 = new StringBuilder();
        for(int j =0; j < bytes.length; j++){
            md5.append(Integer.toString((bytes[j] & 0xff) + 0x100, 16).substring(1));
        }
        return md5.toString();
    }

}
公共类BruteWorker实现可运行{
私有静态最终字符[]alphabet=“eaistnrulodmpcvqgbfjhzxykw0123456789!@$%&*”.tocharray();
私有静态最终int maxLength=8;
私有静态映射散列;
私有静态消息摘要md;
私有字符[]分区;
私有长NBT=0;
BruteWorker(char[]分区,映射哈希){
this.partition=分区;
this.hashes=散列;
}
公开募捐{
System.out.println(“新线程(id=“+thread.currentThread().getId()+”);
试一试{
md=MessageDigest.getInstance(“MD5”);
for(char c:this.partition){
String可能性(String.valueOf(c),maxLength);
}
}捕获(无算法异常){
e、 printStackTrace();
}
System.out.println(“线程结束(id=“+thread.currentThread().getId()+”);
}
//递归类
私有空字符串(字符串前缀,整数长度){
nbc++;
如果((n%10000000)=0){
System.out.println(nbtrys+“thread id=“+thread.currentThread().getId());
}
md.update(prefix.getBytes());
byte[]bytes=md.digest();
字符串md5=getMd5Hash(前缀);
if(hashes.containsKey(md5)){
System.out.println(前缀+“=”+md5);
}
if(prefix.length()
努力了解这里到底发生了什么,如下所示,并行工作并运行良好:

public class Main {
    private static final char[] alphabet = "eaistnrulodmpcvqgbfjhzxykw0123456789!@#$%&*".toCharArray();
    public static void main(String[] args) throws ExecutionException, InterruptedException {
        int cores = Runtime.getRuntime().availableProcessors();
        System.out.println("Number of cores: " + cores); //8 cores

        int partitionSize = alphabet.length / cores;
        ExecutorService service = Executors.newFixedThreadPool(cores);
        List<Future> futures = new ArrayList<Future>();

        for (int c = 0; c < cores; c++) {

            char[] part = Arrays.copyOfRange(alphabet, c * partitionSize, (c + 1) * partitionSize);
            futures.add(service.submit(new BruteWorker(part)));

        }

        for(Future f : futures)
            f.get();

        service.shutdown();
        System.out.println("Completed normally");
    }
    public static class BruteWorker implements Runnable {
        private char[] partition;


        BruteWorker(char[] partition) {
            this.partition = partition;
        }

        public void run() {
            System.out.println("New thread (id = "+ Thread.currentThread().getId() +")");
            for (long nbTries = 0; nbTries < 1_000_000_000L; nbTries ++ ) {
                if((nbTries % 10_000_000) == 0){
                    System.out.println(nbTries + " tries on thread id = "+ Thread.currentThread().getId());
                }
            }
            System.out.println("End of thread (id = "+ Thread.currentThread().getId() +")");
        }
    }    
}

从表面上看,你那里的东西看起来还不错。所以一定有别的事情发生了。您是否确定
brutteworker
实际上是并发运行的(例如,不只是在构造函数中完成所有工作?)。在
run()
方法的入口点和出口处进行几次
println
应该足以确认。您还可以尝试使用调试器(例如Eclipse中的“debug”)运行应用程序,并查看有多少ExecutorService线程正在运行。您问题的标题有点不确定。
Future
对象不负责执行代码:是
ExecutorService
完成了这一任务。
Future
对象只是用来等待并获得计算结果的句柄。我已经用一些println更新了它@GarethDavis@pkalinowExecutorService运行了8个线程,我已经用跟踪和屏幕截图更新了帖子。如果失败,我需要你发布一个完整的,运行的例子,以调试的东西。哦,是的!非常感谢。我已经从我的工作程序中删除了所有静态变量。我现在使用100%的CPUI,我想为所有线程共享一个整数值,我想为所有找到的哈希增加1。一旦这个整数达到5,我想停止所有线程。我怎么能做到这一点?这听起来像是一个新问题的开始:)但你可能想看看“AtomicInteger”,它可能会帮助你
public class Main {
    private static final char[] alphabet = "eaistnrulodmpcvqgbfjhzxykw0123456789!@#$%&*".toCharArray();
    public static void main(String[] args) throws ExecutionException, InterruptedException {
        int cores = Runtime.getRuntime().availableProcessors();
        System.out.println("Number of cores: " + cores); //8 cores

        int partitionSize = alphabet.length / cores;
        ExecutorService service = Executors.newFixedThreadPool(cores);
        List<Future> futures = new ArrayList<Future>();

        for (int c = 0; c < cores; c++) {

            char[] part = Arrays.copyOfRange(alphabet, c * partitionSize, (c + 1) * partitionSize);
            futures.add(service.submit(new BruteWorker(part)));

        }

        for(Future f : futures)
            f.get();

        service.shutdown();
        System.out.println("Completed normally");
    }
    public static class BruteWorker implements Runnable {
        private char[] partition;


        BruteWorker(char[] partition) {
            this.partition = partition;
        }

        public void run() {
            System.out.println("New thread (id = "+ Thread.currentThread().getId() +")");
            for (long nbTries = 0; nbTries < 1_000_000_000L; nbTries ++ ) {
                if((nbTries % 10_000_000) == 0){
                    System.out.println(nbTries + " tries on thread id = "+ Thread.currentThread().getId());
                }
            }
            System.out.println("End of thread (id = "+ Thread.currentThread().getId() +")");
        }
    }    
}
public void run() {
    System.out.println("New thread (id = "+ Thread.currentThread().getId() +")");
    try {
        md = MessageDigest.getInstance("MD5");
        for(char c : this.partition){
            stringPossibilities(String.valueOf(c), maxLength);
        }
    } catch (Exception e) {
        e.printStackTrace();
    } finally {
        System.out.println("End of thread (id = "+ Thread.currentThread().getId() +")");
    }
}