2015-07-27 3 views
-1

Я хочу сделать хэш на каждом предмете из архаиста и в основном вернуть его на главный. Но, например, у этого:java multithreaded hashed ArrayList <String>

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 

, что означает, что программа запуска только последний один поток из тех, кого я ожидал.

ответ

1

Вы сохраняете свою тему в t, которая имеет нулевое значение в начале, но после создания первой темы это больше не пусто, поэтому ваш if не работает и не создается новый поток. Затем вы пытаетесь изменить сообщение, пока этот поток работает ... Честно говоря, все дело в беспорядке. Даже если вы должны были создать 10 потоков, все они указывали бы на один и тот же объект hash(), где переменная сообщения изменяется случайным образом, не зная, действительно ли какой-либо поток уже работает.

Например, следующее может произойти:

  1. Вы начинаете тему для первого сообщения
  2. Тема еще не запущен, но ваш цикл уже устанавливает сообщение для 2-го один
  3. выполняется поток и вычисляет сообщение для второго сообщения.
  4. Сообщение 3 установлено. Ничего не происходит, поскольку Thread уже завершен.
  5. Сообщение 4 установлено, опять же, ничего не происходит, так как резьба делается т.д.

Чтобы это исправить:

  • Удалить переменную из списка хэш.
  • Создайте новый объект hash() для каждого хэш-кода/сообщения
  • Создайте новый поток для каждого объекта hash(). Тогда это должно сработать.
+1

Я бы также добавил изменение родителя класса 'hash' на' Runnable', а не 'Thread', поскольку он никогда не используется как' Thread'. – RealSkeptic

+0

Упс, пропустил это. Очень хорошо, спасибо. –

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() для завершения исправления.

+0

Я сомневаюсь, что это поможет, так как он меняет сообщение в 'this' довольно случайным образом, и все потоки будут обращаться к одному и тому же объекту' this' ... –

+0

@FlorianSchaetz Абсолютно - это обеспечит запуск только десяти потоков. Это не будет касаться проблем синхронизации OP. – dasblinkenlight

+0

Спасибо за вашу помощь, я понимаю некоторые серьезные ошибки, которые я сделал. Не могли бы вы порекомендовать мне ссылку, чтобы больше узнать о потоках? – sifis