java multithreaded hashed ArrayList <string>

时间:2015-07-27 12:39:43

标签: java multithreading arraylist

我想对arraylist中的每个项目进行哈希处理,并基本上将其返回到main。但是例如a有这个:

import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;

public class hash extends Thread {

    private Thread t = null;
    private MessageDigest md = null;
    private StringBuffer sb = null;
    private String message = null;
    private ArrayList<String> list = null;
    private int count = 0;

    public hash(ArrayList<String> list) {
        this.list = list;
    }

    public final void mdstart() {

        for(String item:list){
            this.message=item;
            if(t==null){
                t = new Thread(this);
                t.start();
            }
            count++;
        }
        System.out.println("end: "+this.count);

    }

    @Override
    public final void run() {
        System.out.println("run: "+this.count);
        try {
            md = MessageDigest.getInstance("MD5");
            md.update(this.message.getBytes());

            byte[] digest = md.digest();
            sb = new StringBuffer();
            for (byte hash : digest) {
                sb.append(String.format("%02x", hash));
            }
            System.out.println(this.message + " : " + sb.toString());
        } catch (NoSuchAlgorithmException ex) {
            System.out.println("no such algorithm exception : md5");
            System.exit(1);
        }
    }

    public static void main(String args[]) {

        ArrayList<String> list = new ArrayList<>();
        for (int i = 0; i < 10; i++) {
            list.add("message" + i);
        }
        new hash(list).mdstart();      
    }
}

,输出为:

end: 10
run: 10
message9 : 99f72d2de922c1f14b0ba5e145f06544

这意味着程序只运行我期望的最后一个线程。

2 个答案:

答案 0 :(得分:1)

您将线程存储在t中,在开始时为空,但在创建第一个线程后,它不再为空,因此您的if失败并且没有创建新的线程。然后你尝试在这个Thread运行的时候修改消息...... Honestely,整个事情是一团糟。即使您要创建10个线程,它们也会指向相同的hash()对象,其中消息变量随机变化,而不知道是否有任何线程已经完成工作。

例如,可能会发生以下情况:

  1. 您启动第一条消息的话题
  2. 线程尚未运行,但您的for循环已将消息设置为第二个
  3. 线程运行并计算第二条消息的消息
  4. 设置了消息3。没有任何事情发生,因为Thread已经完成。
  5. 设置消息4,再次,线程完成后没有任何反应 等
  6. 修复它:

    • 从哈希中删除列表变量。
    • 为每个哈希码/消息创建一个新的hash()对象
    • 为每个hash()对象启动一个新线程。然后它应该工作。

答案 1 :(得分:0)

问题是你的代码只会启动一个线程:

if(t==null){
    t = new Thread(this);
    t.start();
}

第一个线程启动后,t不再是null,因此不会创建新线程。

要解决此问题,请创建一个线程数组,并将threads[count++]设置为循环中新创建的线程。循环结束后,您可以join线程确保它们在mdstart()返回之前完成:

public final void mdstart() {
    Thread[] threads = new Thread[list.size()];
    for(String item:list){
        this.message=item;
        threads[count] = new Thread(this);
        threads[count].start();
        count++;
    }
    for (Thread t : threads) {
        t.join();
    }
    System.out.println("end: "+this.count);
}

注意:这将修复代码的启动部分。您需要在run()方法中处理同步问题才能完成修复。