Pessoal, estou fazendo um cógido que lê um arquivo onde cada linha é um registro, a classe principal quebra estes registros em listas de 2000 registros, onde para cada lista cria uma thread para a classe que vai processar registro a registro da lista.
A minha dúvida é se tem algo que eu possa estar fazendo para melhorar a performance?
E o consumo de memória, estou fazendo algo que o prejudique ?
A forma que estou implementando está legal ?
segue o código:
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
public class Processo {
public static BufferedWriter writer;
public static int qtTotalItens = 0;
public static int qtTotalGravada = 0;
public static void main(String[] args) throws IOException {
//Recupera a variavel com o caminho do arquivo de leitura e instancia o leitor
BufferedReader reader = new BufferedReader(new FileReader("c:/entrada.txt"));
//Recupera a variavel com o caminho do arquivo de escrita e instancia o escritor
writer = new BufferedWriter(new FileWriter("c:/saida.txt"));
while(reader.ready()){
//limita a quantidade de Threads
if(Thread.activeCount()<=15){
String[] listaRegistros = new String[2000];
for (int i = 0; i < 2000; i++) {
listaRegistros[i] = reader.readLine();
if(!reader.ready()){
break;
}
}
//Instancia um thread para avaliação
Thread thread = new Thread(new Efetua(listaRegistros));
thread.start();
//tive que forçar o gc, porque no unix estava estourando memory exception, acredito que tenha faltado memória para startar a thread do gc
if((Runtime.getRuntime().totalMemory()/5)>Runtime.getRuntime().freeMemory()){
System.out.println("garbage");
System.gc();
}
}
}
}
public static synchronized void writeOutputFile(String[] listaRetornos) throws IOException{
//Faz a gravação dos registros encontrados
for (int i = 0; i < listaRetornos.length; i++) {
if(listaRetornos[i] != null){
writer.write(listaRetornos[i]);
writer.newLine();
qtTotalGravada++;
}
}
writer.flush();
//Se ja gravou todos os itens fecha o arquivo
if(qtTotalGravada == qtTotalItens){
writer.close();
return;
}
}
}
Segue a classe que é chamada pela thread, onde leio os registros da lista e realizo um processamento registro a registro. No final eu mando gravar um arquivo de saída pelo método synchronized da classe Processo
import java.io.FileNotFoundException;
import java.io.IOException;
import java.text.ParseException;
import java.util.LinkedHashMap;
import java.util.Map;
import Util;
public class Efetua implements Runnable {
private String[] listaRegistros;
private String[] listaRetorno;
public Efetua(String[] listaRegistros) {
this.listaRegistros = listaRegistros;
this.listaRetorno = new String[listaRegistros.length];
}
public void run() {
for (int i = 0; i < listaRegistros.length; i++) {
String bufferEntrada = listaRegistros[i];
//Caso chegue no fim do array
if (bufferEntrada == null) {
break;
}
//Caso seja o registro de header
if (bufferEntrada.charAt(0) == 'A') {
continue;
}
//Caso seja o registro de trailer
if (bufferEntrada.charAt(0) == 'Z') {
Processo.qtTotalItens =
Integer.parseInt(bufferEntrada.substring(1, 16));
break;
}
//despreza o primeiro caracter que é um indicativo de registro.
bufferEntrada = bufferEntrada.substring(1, bufferEntrada.length());
//Executa o processamento das informações através de uma classe utilitária
//Este processo demora um pouco, por isto que a implementação foi feita utilizando threads.
listaRetorno[i] = Util.processa(bufferEntrada);
bufferEntrada = null;
}
//Grava resultado no aquivo passando a listagem de registros das avaliações
try {
Processo.writeOutputFile(listaRetorno);
listaRegistros = null;
listaRetorno = null;
} catch (IOException e) { //Caso a escrita nao esteja OK lança uma mensagem
System.out.println(
Thread.currentThread().getName() + ":" + e.getMessage());
System.exit(07);
}
}
}
[ ]'s