2016-12-01 2 views
2

Я пытаюсь, чтобы каждый поток обращался к одному элементу цикла for, а другой поток обратился к следующему элементу. Я хочу сделать это, используя несколько потоков, и количество созданных нескольких потоков будет введено пользователем. Я сделал это с помощью службы executorservices и потоков. Я хочу сделать это, используя простые потоки. Правильно ли это? Есть ли способ лучше?Многопоточность/Параллелизация каждого элемента цикла for JAVA

Map<String, String> fileMap = new HashMap<>(); 
fileMap.put("Age", "Age is not remotely associated with it."); 
fileMap.put("Gender", "Gender plays a role but not that important."); 
fileMap.put("Money", "People do not believe but this is the only factor that matters."); 

Runnable myRunnable = new Runnable(){ 
    public void run(){ 
     for (Map.Entry<String, String> entry : fileMap.entrySet()) { 
      synchronized(this){ 
       int counter = 0; 
       Pattern p = Pattern.compile("not"); 
       Matcher m = p.matcher(entry.getValue()); 
       while (m.find()) { 
        counter++; 
       } 
       System.out.println("File Name: " + entry.getKey()); 
       System.out.println("Count: " + counter); 
       System.out.println(Thread.currentThread().getName()); 
      } 
     } 
    }  
}; 

int n = Integer.parseInt(args[0]); 
for (int x=0; x<n; x++) 
{ 
    Thread temp= new Thread(myRunnable, "Thread #" + x); 
    temp.start(); 
    System.out.println("Started Thread:" + x); 
} 

Кроме того, можно иметь резьбу, чтобы не вернуться к предыдущему пункту, так как в предыдущей теме уже вычисленного значения? Любая помощь будет оценена по достоинству. Thanks

+0

Кажется бессмысленным иметь потоки, а затем попытаться заблокировать его из-за 'synchronized'. хотя в этом случае это «это»? Если вы хотите предотвратить повторную обработку уже найденных строк, то, возможно, удалите его из 'map' –

+0

Неясно, что вы подразумеваете под простой нитью. В потоках Java нет индексов (например, вы видите в OpenCL/Cuda), поэтому вам нужно расширить функциональность потоков, если вы хотите дать им индексы, хотя ваш runable COULD удерживает индекс. Ваша логика в этом приложении также ошибочна, поскольку количество создаваемых потоков не всегда будет соответствовать количеству обрабатываемых вами элементов. Минимально я бы изменил цикл for от 'x

+0

@RalphRitoch Извините, мой английский. Я имел в виду «делать это, используя простые потоки», а не через ExecutorService или любой другой пакет. Просто потоки вместе с, возможно, Maps/ConcurrentHashMaps – Tao

ответ

1

Это решение проблемы. Это анализирует имя потока для предоставления индекса и использует конечные массивы для обработки передаваемых данных в потоки.

Map<String, String> fileMap = new HashMap<>(); 
fileMap.put("Age", "Age is not remotely associated with it."); 
fileMap.put("Gender", "Gender plays a role but not that important."); 
fileMap.put("Money", "People do not believe but this is the only factor that matters."); 


final int[] tgSize = new int[]{0}; 
final Map.Entry[][] entryArr = new Map.Entry[1][]; 

Runnable myRunnable = new Runnable(){ 
    public void run(){ 
     Integer index = Integer.valueOf(Thread.currentThread().getName().substring(8)); 

     for(int i = index; i < fileMap.size(); i += tgSize[0]) { 
      int counter = 0; 
      @SuppressWarnings("unchecked") 
      Map.Entry<String, String> entry = entryArr[0][i]; 
      Pattern p = Pattern.compile("not"); 
      Matcher m = p.matcher(entry.getValue()); 
      while (m.find()) { 
       counter++; 
      } 
      synchronized(this) { 
       System.out.println("File Name: " + entry.getKey()); 
       System.out.println("Count: " + counter); 
       System.out.println(Thread.currentThread().getName());    
      } 
     } 
    }  
}; 

int n = Integer.parseInt(args[0]); 

tgSize[0] = n < fileMap.size() ? n : fileMap.size(); 
entryArr[0] = fileMap.entrySet().toArray(new Map.Entry[fileMap.size()]); 


for (int x=0; x<n && x < fileMap.size(); x++) 
{ 
    Thread temp= new Thread(myRunnable, "Thread #" + x); 
    temp.start(); 
    System.out.println("Started Thread:" + x); 
} 
+0

Спасибо. Это прекрасно работает и то, что я искал. Но можете ли вы сообщить мне, почему нам нужно создать Map.Entry [] []? – Tao

+0

Я понял. Его переход к массиву для последующей обработки, правильно? – Tao

+0

Правильно, это зеркало обработки GPU. Сначала вы устанавливаете данные в глобальную память, а затем обрабатываете элементы с помощью индекса, чтобы гарантировать, что шейдеры не выполняют одну и ту же работу. Конечные массивы - хороший способ имитировать глобальную (общую) память в java. –

1

Это может быть достигнуто путем paralledStream AbacusUtil

final Pattern p = Pattern.compile("not"); 

Stream.of(fileMap).parallel(threadNum).map(entry -> { 
    Matcher m = p.matcher(entry.getValue()); 
    int count = 0; 
    while (m.find()) { 
     count++; 
    } 
    return Pair.of(entry.getKey(), count); 
}).forEach(entry -> { 
    N.println("File Name: " + entry.getKey() + ", Count: " + entry.getValue()); 
}); 

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

final int threadNum = 3; 
final ExecutorService executorService = Executors.newFixedThreadPool(threadNum); 
final Iterator<Entry<String, String>> iter = fileMap.entrySet().iterator(); 

for (int i = 0; i < threadNum; i++) { 
    executorService.execute(new Runnable() { 
     @Override 
     public void run() { 
      Entry<String, String> entry = null; 
      while (true) { 
       synchronized (iter) { 
        if (iter.hasNext() == false) { 
         break; 
        } 
        entry = iter.next(); 
       } 

       final Matcher m = p.matcher(entry.getValue()); 
       int count = 0; 
       while (m.find()) { 
        count++; 
       } 

       System.out.println("File Name: " + entry.getKey() + ", Count: " + count + ", thread: " + Thread.currentThread().getName()); 
      } 
     } 
    }); 
} 

Объявление: Я являюсь разработчиком AbacusUtil.

+0

Хорошая библиотека, но он сказал в вопросе, что хочет использовать «простые» потоки. Он также не определил, что он означает простым. –

+0

Является ли ваша библиотека на maven? –

+0

Эй, мне очень понравилась эта библиотека, которую вы упомянули! – GOXR3PLUS

0

Стандартный способ распараллеливания цикла с использованием необработанных потоков, итераций по массиву, показан ниже, используя вашу проблему.

import java.util.*; 
import java.util.regex.*; 

public class MyClass { 

public static void main(String[] args) { 
    Map<String, String> fileMap = new HashMap<>(); 
    fileMap.put("Age", "Age is not remotely associated with it."); 
    fileMap.put("Gender", "Gender plays a role but not that important."); 
    fileMap.put("Money", "People do not believe but this is the only factor that matters."); 
    String[] keys = fileMap.keySet().toArray(new String[fileMap.size()]); 

    int n = 2; //Integer.parseInt(args[0]); 
    for (int x=0; x<n; x++) 
    { 
     Runnable myRunnable = new MyRunnable(fileMap, keys, x, n); 
     Thread temp= new Thread(myRunnable); 
     temp.start(); 
     //System.out.println("Started Thread:" + x); 
    } 
} 

    private static class MyRunnable implements Runnable { 
     private Map<String, String> fileMap; 
     private String[] keys; 
     private int threadID; 
     private int threadCount; 
     Pattern p = Pattern.compile("not"); 
     public MyRunnable(Map<String, String> fileMap, String[] keys, int threadID, int threadCount) { 
      this.fileMap = fileMap; 
      this.keys = keys; 
      this.threadID = threadID; 
      this.threadCount = threadCount; 
     } 
     public void run(){ 
      for (int i=threadID; i<keys.length; i+= threadCount) { 
       int counter = 0; 
       Matcher m = p.matcher(fileMap.get(keys[i])); 
       while (m.find()) { 
        counter++; 
       } 
       synchronized(MyClass.class){ 
        System.out.println("File Name: " + keys[i]); 
        System.out.println("Count: " + counter); 
        System.out.println("ThreadID: " + threadID); 
       } 
      } 
     }  
    } 
    } 
+0

Спасибо. Я пытался это сделать, не создавая другого класса. Но решение проще. спасибо – Tao

Смежные вопросы