2013-10-17 5 views
6

Ich habe einen kontinuierlichen laufenden Thread in meiner Anwendung, die aus einem HashSet besteht, um alle Symbole in der Anwendung zu speichern. Gemäß dem Design zu dem Zeitpunkt, als es geschrieben wurde, wird innerhalb der wahren Bedingung des Threads das Hashset kontinuierlich durchlaufen und die Datenbank für alle in HashSet enthaltenen Symbole aktualisiert.Ein Set in kleinere Subsets partitionieren und als Batch verarbeiten

Die maximalen Symbole, die im Hashset vorhanden sein können, liegen bei 6000. Ich dont die db mit all den 6000 Symbolen auf einmal, aber teilen Sie dieses hashset in verschiedene Teilmengen von je 500 (12 Sets) und führen Sie jedes Subset einzeln aus und lassen Sie einen Thread nach jedem Subset für 15 Minuten schlafen, so dass ich das reduzieren kann Druck auf die Datenbank.

Dies ist mein Code, (Beispielcode-Schnipsel)

Wie ich ein Sets in kleinere Teilmengen und Verfahren, Partition kann (ich habe für Partitionierung Arraylist, TreeSet die Beispiele gesehen, aber fand kein Beispiel verwandtes zu HashSet) so etwas wie

package com.ubsc.rewji.threads; 

import java.util.Arrays; 
import java.util.Collections; 
import java.util.HashSet; 
import java.util.Iterator; 
import java.util.Set; 
import java.util.concurrent.PriorityBlockingQueue; 

public class TaskerThread extends Thread { 
    private PriorityBlockingQueue<String> priorityBlocking = new PriorityBlockingQueue<String>(); 
    String symbols[] = new String[] { "One", "Two", "Three", "Four" }; 
    Set<String> allSymbolsSet = Collections 
      .synchronizedSet(new HashSet<String>(Arrays.asList(symbols))); 

    public void addsymbols(String commaDelimSymbolsList) { 
     if (commaDelimSymbolsList != null) { 
      String[] symAr = commaDelimSymbolsList.split(","); 
      for (int i = 0; i < symAr.length; i++) { 
       priorityBlocking.add(symAr[i]); 
      } 
     } 
    } 

    public void run() { 
     while (true) { 
      try { 
       while (priorityBlocking.peek() != null) { 
        String symbol = priorityBlocking.poll(); 
        allSymbolsSet.add(symbol); 
       } 
       Iterator<String> ite = allSymbolsSet.iterator(); 
       System.out.println("======================="); 
       while (ite.hasNext()) { 
        String symbol = ite.next(); 
        if (symbol != null && symbol.trim().length() > 0) { 
         try { 
          updateDB(symbol); 

         } catch (Exception e) { 
          e.printStackTrace(); 
         } 
        } 
       } 
       Thread.sleep(2000); 
      } catch (Exception e) { 
       e.printStackTrace(); 
      } 
     } 
    } 

    public void updateDB(String symbol) { 
     System.out.println("THE SYMBOL BEING UPDATED IS" + " " + symbol); 
    } 

    public static void main(String args[]) { 
     TaskerThread taskThread = new TaskerThread(); 
     taskThread.start(); 

     String commaDelimSymbolsList = "ONVO,HJI,HYU,SD,F,SDF,ASA,TRET,TRE,JHG,RWE,XCX,WQE,KLJK,XCZ"; 
     taskThread.addsymbols(commaDelimSymbolsList); 

    } 

} 
+0

Das Konzept der "Druck" auf DataBases ist ein seltsamer ... DBs in der Regel sehr gut in der Lage, diesen "Druck" anmutig zu behandeln. – TwoThe

Antwort

9

Do

private static final int PARTITIONS_COUNT = 12; 

List<Set<Type>> theSets = new ArrayList<Set<Type>>(PARTITIONS_COUNT); 
for (int i = 0; i < PARTITIONS_COUNT; i++) { 
    theSets.add(new HashSet<Type>()); 
} 

int index = 0; 
for (Type object : originalSet) { 
    theSets.get(index++ % PARTITIONS_COUNT).add(Object); 
} 

Jetzt haben Sie die originalSet in 12 anderen HashSets verteilt.

+0

danke Amir Pashazadeh, die Nummer 12 ist nicht festgelegt, ich möchte nur die Didvide-Elemente in Allsymbol in verschiedenen Sub-Hashset, so dass jede Teilmenge wird 500 Elemente enthalten – Pawan

+0

Wahrscheinlich nicht die beste Lösung für sein Problem, aber gute Idee. – TwoThe

+0

@TwoThe Kann ich wissen, was wäre die gute Idee wäre aus Ihrer Sicht? – Pawan

0

Eine sehr einfache Art und Weise für Ihr eigentliches Problem wäre der Code wie folgt zu ändern:

Iterator<String> ite = allSymbolsSet.iterator(); 
System.out.println("======================="); 
int i = 500; 
while ((--i > 0) && ite.hasNext()) { 

Eine allgemeine Methode wäre, den Iterator zu verwenden, um die Elemente einer nach der anderen in einer einfachen Schleife zu nehmen:

int i = 500; 
while ((--i > 0) && ite.hasNext()) { 
    sublist.add(ite.next()); 
    ite.remove(); 
} 
+0

Warum entfernen Sie die Elemente aus dem Iterator? – Pawan

+0

Sie müssen das nicht, aber wenn Sie das nicht tun, müssten Sie Ihre aktuelle Listenposition auf andere Weise notieren. Das Problem ist, dass der nächste Aufruf dieses Codes keine Unterliste mit den gleichen Elementen erneut erstellen darf. – TwoThe

24

Mit Guava:

for (List<String> partition : Iterables.partition(yourSet, 500)) { 
    // ... handle partition ... 
} 
1

Wir verwenden Sie die folgende ca. oach, um ein Set zu teilen.

Wir werden die Ausgabe als erhalten [a, b] [c, d] [e] `

private static List<Set<String>> partitionSet(Set<String> set, int  partitionSize) 
{ 
    List<Set<String>> list = new ArrayList<>(); 
    int setSize = set.size(); 

    Iterator iterator = set.iterator(); 

    while(iterator.hasNext()) 
    { 
     Set newSet = new HashSet(); 
     for(int j = 0; j < partitionSize && iterator.hasNext(); j++) 
     { 
      String s = (String)iterator.next(); 
      newSet.add(s); 
     } 
     list.add(newSet); 
    } 
    return list; 
} 

public static void main(String[] args) 
{ 
    Set<String> set = new HashSet<>(); 
    set.add("a"); 
    set.add("b"); 
    set.add("c"); 
    set.add("d"); 
    set.add("e"); 

    int size = 2; 
    List<Set<String>> list = partitionSet(set, 2); 

    for(int i = 0; i < list.size(); i++) 
    { 
     Set<String> s = list.get(i); 
     System.out.println(s); 
    } 
}