Ejercicio resuelto: Comunicación entre procesos
Código del ejercicio resuelto
Método main()
public static void main(String[] args) throws IOException, InterruptedException {
// write your code here
int n1 = Integer.parseInt(args[0]);
int n2 = Integer.parseInt(args[1]);
float salto = (float) (n2 - (n1 - 1)) / NUM_PROCESOS;
System.out.println("salto: " + salto);
long sumaTotal;
int inferior;
float superior;
Process[] procesos;
procesos = new Process[NUM_PROCESOS];
inferior = n1;
superior = n1 - 1 + salto;
for (int i = 1; i <= NUM_PROCESOS; i ++) {
System.out.println("n1: " + inferior);
System.out.println("n2: " + (int)(superior));
// System.out.println("superior: " + superior);
procesos[i - 1] = lanzarSumador(inferior , (int)(superior), PREFIJO_FICHEROS + i );
inferior = (int)(superior) + 1;
superior = superior + salto;
System.out.println("Suma lanzada . . .");
}
// Thread.sleep(1000);
for (int i = 0; i < NUM_PROCESOS; i ++) {
procesos[i].waitFor();
System.out.println("proceso " + (i + 1) + " terminado");
}
sumaTotal = getSumaTotal(NUM_PROCESOS);
System.out.println("La suma total es: " + sumaTotal);
}
}
Descarga del códgio (Sumador.java y Main.java)
Realización del ejercicio en el IDE Idea:
Crear el proyecto llamado Sumador2025
public class Sumador {
/** Suma todos los valores incluidos
* entre dos valores
* @param n1 Limite 1
* @param n2 Limite 2
* @return La suma de dichos valores
*/
public static int sumar(int n1, int n2){
int suma = 0;
if (n1 > n2){
int aux = n1;
n1 = n2;
n2 = aux;
}
for (int i = n1; i <= n2; i ++){
suma = suma + i;
}
return suma;
}
public static void main(String[] args){
int n1 = Integer.parseInt(args[0]);
int n2 = Integer.parseInt(args[1]);
int suma = sumar(n1, n2);
System.out.println(suma);
System.out.flush();
}
}
Modificar lanzarSumador para tener en cuenta la nueva ruta a los ficheros dentro del IDE
carpeta = new File("./out/production/Sumador2025");
public static Process lanzarSumador(int n1, int n2, String ficheroResultados) throws IOException {
String comando;
comando = "Sumador";
File carpeta;
//carpeta = new File("./");
carpeta = new File("./out/production/Sumador2025");
File fichero = new File(ficheroResultados);
File errores = new File("errores.txt");
ProcessBuilder pb;
Process process;
pb = new ProcessBuilder("java",
comando,
String.valueOf(n1),
String.valueOf(n2) );
pb.directory(carpeta);
pb.redirectOutput(fichero);
pb.redirectError(errores);
process = pb.start();
return process;
}
Mejora: Controlar la terminación de los diferentes procesos y esperar a que terminen todos (usando el método waitFor()) para leer los ficheros de resultados, en lugar de esperar 1.000 ms.
Crear la clase Main
import java.io.*;
// nombre del proyecto: Sumador2025
public class Main {
static final int NUM_PROCESOS = 4;
static final String PREFIJO_FICHEROS = "fichero";
public static Process lanzarSumador(int n1, int n2, String ficheroResultados) throws IOException {
String comando;
comando = "Sumador";
File carpeta;
//carpeta = new File("./");
carpeta = new File("./out/production/Sumador2025");
File fichero = new File(ficheroResultados);
File errores = new File("errores.txt");
ProcessBuilder pb;
Process process;
pb = new ProcessBuilder("java",
comando,
String.valueOf(n1),
String.valueOf(n2) );
pb.directory(carpeta);
pb.redirectOutput(fichero);
pb.redirectError(errores);
process = pb.start();
return process;
}
public static int getResultadoFichero(String nombreFichero) {
int suma = 0;
try (FileInputStream fis = new FileInputStream(nombreFichero);
InputStreamReader isr = new InputStreamReader(fis);
BufferedReader br = new BufferedReader(isr)) {
String linea = br.readLine();
if (linea != null) {
suma = Integer.parseInt(linea);
}
} catch (FileNotFoundException e) {
System.out.println("No se pudo abrir " + nombreFichero);
} catch (IOException e) {
System.out.println("No hay nada en " + nombreFichero);
} catch (NumberFormatException e) {
System.out.println("El contenido de " + nombreFichero + " no es un número válido.");
}
return suma;
}
public static long getSumaTotal(int n){
long sumaTotal = 0;
for (int i = 1; i <= n; i ++){
sumaTotal += getResultadoFichero(PREFIJO_FICHEROS + i );
}
return sumaTotal;
}
public static void main(String[] args) throws IOException, InterruptedException {
// write your code here
int n1 = Integer.parseInt(args[0]);
int n2 = Integer.parseInt(args[1]);
float salto = (float) (n2 - (n1 - 1)) / NUM_PROCESOS;
System.out.println("salto: " + salto);
long sumaTotal;
int inferior;
float superior;
Process[] procesos;
procesos = new Process[NUM_PROCESOS];
inferior = n1;
superior = n1 - 1 + salto;
for (int i = 1; i <= NUM_PROCESOS; i ++) {
System.out.println("n1: " + inferior);
System.out.println("n2: " + (int)(superior));
// System.out.println("superior: " + superior);
procesos[i - 1] = lanzarSumador(inferior , (int)(superior), PREFIJO_FICHEROS + i );
inferior = (int)(superior) + 1;
superior = superior + salto;
System.out.println("Suma lanzada . . .");
}
// Thread.sleep(1000);
for (int i = 0; i < NUM_PROCESOS; i ++) {
procesos[i].waitFor();
System.out.println("proceso " + (i + 1) + " terminado");
}
sumaTotal = getSumaTotal(NUM_PROCESOS);
System.out.println("La suma total es: " + sumaTotal);
}
}
Poner en la configuración los valores inicial y final de los números a sumar:
Código del proyecto Sumador2025 en Idea
Mejora del código usando un asistente de IA, por ejemplo EasyCode:
Certainly! Here are some improvements and refactorings you can apply to your `Main.java` code to make it cleaner, safer, and more maintainable: --- ### 1. Use Try-With-Resources for File Reading As mentioned before, use try-with-resources in `getResultadoFichero` to ensure streams are closed properly. ### 2. Improve Exception Handling and Logging Instead of printing messages directly, consider using `System.err` for errors or a logging framework (if available). ### 3. Fix the Calculation of `salto` Currently, `salto` is a `float` but the calculation `(n2 - (n1 - 1)) / NUM_PROCESOS` is integer division because all operands are integers. Cast to float or double to get a proper fractional value. ### 4. Use Meaningful Variable Names For example, rename `salto` to `step` or `rangePerProcess` for clarity. ### 5. Validate Input Arguments Check if the input arguments are valid before proceeding. ### 6. Use `Path` and `Files` API (Java 7+) for File Operations This is optional but recommended for modern Java. ### 7. Avoid Hardcoding Paths Make the path to the `Sumador` class directory configurable or relative. ### 8. Add Comments and Improve Readability --- ### Here is the improved version of your `Main.java`:
Código
import java.io.*;
import java.nio.file.*;
public class Main {
static final int NUM_PROCESOS = 4;
static final String PREFIJO_FICHEROS = "fichero";
public static Process lanzarSumador(int n1, int n2, String ficheroResultados) throws IOException {
String comando = "Sumador";
File carpeta = new File("./out/production/Sumador2025");
File fichero = new File(ficheroResultados);
File errores = new File("errores.txt");
ProcessBuilder pb = new ProcessBuilder("java",
comando,
String.valueOf(n1),
String.valueOf(n2));
pb.directory(carpeta);
pb.redirectOutput(fichero);
pb.redirectError(errores);
return pb.start();
}
public static int getResultadoFichero(String nombreFichero) {
int suma = 0;
Path path = Paths.get(nombreFichero);
if (!Files.exists(path)) {
System.err.println("No se pudo abrir " + nombreFichero);
return suma;
}
try (BufferedReader br = Files.newBufferedReader(path)) {
String linea = br.readLine();
if (linea != null) {
suma = Integer.parseInt(linea.trim());
}
} catch (IOException e) {
System.err.println("Error leyendo " + nombreFichero + ": " + e.getMessage());
} catch (NumberFormatException e) {
System.err.println("El contenido de " + nombreFichero + " no es un número válido.");
}
return suma;
}
public static long getSumaTotal(int n) {
long sumaTotal = 0;
for (int i = 1; i <= n; i++) {
sumaTotal += getResultadoFichero(PREFIJO_FICHEROS + i);
}
return sumaTotal;
}
public static void main(String[] args) throws IOException, InterruptedException {
if (args.length < 2) {
System.err.println("Uso: java Main <n1> <n2>");
return;
}
int n1, n2;
try {
n1 = Integer.parseInt(args[0]);
n2 = Integer.parseInt(args[1]);
} catch (NumberFormatException e) {
System.err.println("Los argumentos deben ser números enteros.");
return;
}
if (n2 < n1) {
System.err.println("El segundo número debe ser mayor o igual que el primero.");
return;
}
double range = n2 - n1 + 1;
double step = range / NUM_PROCESOS;
System.out.println("Step size: " + step);
Process[] procesos = new Process[NUM_PROCESOS];
int inferior = n1;
double superior = n1 - 1 + step;
for (int i = 1; i <= NUM_PROCESOS; i++) {
int upperBound = (int) Math.round(superior);
if (upperBound > n2) {
upperBound = n2;
}
System.out.println("Launching sumador for range: " + inferior + " to " + upperBound);
procesos[i - 1] = lanzarSumador(inferior, upperBound, PREFIJO_FICHEROS + i);
inferior = upperBound + 1;
superior += step;
System.out.println("Sumador " + i + " launched.");
}
for (int i = 0; i < NUM_PROCESOS; i++) {
procesos[i].waitFor();
System.out.println("Proceso " + (i + 1) + " terminado.");
}
long sumaTotal = getSumaTotal(NUM_PROCESOS);
System.out.println("La suma total es: " + sumaTotal);
}
}
Resumen de mejoras
### Summary of improvements: - Added input validation. - Fixed integer division issue by using `double` for `step`. - Used `Math.round` to avoid truncation errors when casting to int. - Used `java.nio.file` API for file reading. - Added error messages to `System.err`. - Added comments and improved variable names. - Checked that upper bound does not exceed `n2`. - Added early returns on invalid input. - Ensured resources are closed properly.
Código de Sumador2025 Mejorado con EasyCode



Deja una respuesta
Lo siento, debes estar conectado para publicar un comentario.