Comment faire pour lire les fichiers en mode multithread?
J'ai actuellement un programme qui lit les fichier (très grand) en mono-thread mode et crée des index de recherche, mais il prend trop de temps à l'index en mono-thread environnement.
Maintenant, je suis en train de le faire fonctionner en mode multithread mais vous ne savez pas la meilleure façon d'y parvenir.
Mon programme principal crée un tampon lecteur et passe à l'instance de fil et le fil utilise de la mémoire tampon lecteur instance de lire les fichiers.
Je ne pense pas que cela fonctionne comme prévu plutôt chaque thread est la lecture de la même ligne, encore et encore.
Est-il un moyen de rendre les threads de lire uniquement les lignes qui ne sont pas lus par d'autres thread? Ai-je besoin de diviser le fichier? Est-il un moyen de mettre en œuvre ce, sans fractionnement du fichier?
Exemple de programme Principal:
import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.util.ArrayList;
public class TestMTFile {
public static void main(String args[]) {
BufferedReader reader = null;
ArrayList<Thread> threads = new ArrayList<Thread>();
try {
reader = new BufferedReader(new FileReader(
"test.tsv"));
} catch (FileNotFoundException e1) {
e1.printStackTrace();
}
for (int i = 0; i <= 10; i++) {
Runnable task = new ReadFileMT(reader);
Thread worker = new Thread(task);
//We can set the name of the thread
worker.setName(String.valueOf(i));
//Start the thread, never call method run() direct
worker.start();
//Remember the thread for later usage
threads.add(worker);
}
int running = 0;
int runner1 = 0;
int runner2 = 0;
do {
running = 0;
for (Thread thread : threads) {
if (thread.isAlive()) {
runner1 = running++;
}
}
if (runner2 != runner1) {
runner2 = runner1;
System.out.println("We have " + runner2 + " running threads. ");
}
} while (running > 0);
if (running == 0) {
System.out.println("Ended");
}
}
}
Fil:
import java.io.BufferedReader;
import java.io.IOException;
public class ReadFileMT implements Runnable {
BufferedReader bReader = null;
ReadFileMT(BufferedReader reader) {
this.bReader = reader;
}
public synchronized void run() {
String line;
try {
while ((line = bReader.readLine()) != null) {
try {
System.out.println(line);
} catch (Exception e) {
}
}
} catch (IOException e) {
//TODO Auto-generated catch block
e.printStackTrace();
}
}
}
- Vous êtes en se concentrant sur la mauvaise partie. C'est l'indexation, vous devez multi-thread, pas la lecture.
- je doute fortement de le goulet d'étranglement est la lecture du fichier. c'est probablement la de l'indexation.
Vous devez vous connecter pour publier un commentaire.
Le goulot d'étranglement est le plus susceptible de l'indexation, pas la lecture du fichier. en supposant que votre système d'indexation prend en charge plusieurs threads, vous voulez probablement un producteur/consommateur, le programme d'installation avec un fil de la lecture du fichier et en le poussant à chaque ligne dans un BlockingQueue (le producteur), et plusieurs threads lignes de traction de la BlockingQueue et de les pousser dans l'index (les consommateurs).
Voir ce fil - si vos fichiers sont tous sur le même disque, alors vous ne pouvez pas faire mieux que de les lire avec un seul thread, même si il peut être possible de processus les fichiers avec plusieurs threads une fois que vous avez lu dans la mémoire principale.
Si vous pouvez utiliser Java 8, vous pourriez être en mesure de le faire rapidement et facilement à l'aide de l'API de Flux. Lire le fichier dans un MappedByteBuffer, qui peut ouvrir un fichier jusqu'à 2 go très rapidement, puis de lire les lignes de la mémoire tampon (vous devez vous assurer que votre JVM dispose de suffisamment de mémoire supplémentaire pour stocker le fichier):
Tout d'abord, je suis d'accord avec @Zim-Zam que c'est le fichier IO, pas l'indexation, c'est probable que le taux de la détermination de l'étape. (Si je suis en désaccord avec @jtahlborn). Dépend de la complexité de l'indexation est.
Deuxième, dans votre code, chaque thread a son propre, indépendante
BufferedReader
. Par conséquent, ils seront tous de lire l'intégralité du fichier. Une solution possible est d'utiliser une seuleBufferedReader
qu'ils partagent. Et puis vous avez besoin de synchroniser leBufferedReader.readLine()
méthode (je pense) depuis la javadoc sont muets sur la possibilitéBufferedReader
est thread-safe. Et, puisque je pense que l'OI est botleneck, cela va devenir le goulot d'étranglement et je doute si le multithreading vous gagnera beaucoup. Mais lui donner un essai, j'ai eu tort de temps en temps. 🙂p.s. Je suis d'accord avec @jtahlmorn qu'un producteur/consommateur motif est mieux que ma part le BufferedReader idée, mais ce serait beaucoup plus de travail pour vous.