Synchronize threads in Java

2

I have an exercise of threads to record and read a text file in Java, but what I do not get is that the threads are synchronized. In the way I have it, the threads interfere with each other, and at the time of writing in the file the thread for reading comes into play at the same time. How could I synchronize the threads in the code I have? Thanks in advance.

Code:

public class Ejercicio7 extends Thread
{       
    public static void main(String[] args)
    {
        Thread hilo1 = new Ejercicio7(); hilo1.setName("hilo1");
        Thread hilo2 = new Ejercicio7(); hilo2.setName("hilo2");

        hilo1.start();
        hilo2.start();
    }

    public void run()
    {
        if(Thread.currentThread().getName().equals("hilo1"))
        {
            grabarFicheroTexto();
        }
        else
        {           
            try {
                leerFicheroTexto();
            } catch (IOException e) {e.printStackTrace();}          
        }
    }

    public static void grabarFicheroTexto()
    {
        char c;
        try{
            System.out.println("Vas a escribir en un fichero de texto en Java\n");
            System.out.print("Escribe aqui: ");
            FileWriter fichero=new FileWriter("..\Threads\src\ejercicio7\Archivo.txt");
            StringBuffer str=new StringBuffer();
            while ((c=(char)System.in.read())!='\n')
                str.append(c);
            String cadena=new String(str);  
            fichero.write(cadena);          

            if (fichero!=null)
                fichero.close();
        }catch(IOException ex){}
        System.out.println("FICHERO ESCRITO CORRECTAMENTE");
    }
    public static void leerFicheroTexto()throws IOException
    {
        System.out.println("Estas leyendo un fichero de texto en Java\n");
        FileReader fr = new FileReader("..\Threads\src\ejercicio7\Archivo.txt");
        BufferedReader br = new BufferedReader(fr);
        String s;

        while((s = br.readLine()) != null) {
          System.out.println(s);
        }
        fr.close();
    }
}
    
asked by Mario Guiber 11.11.2017 в 15:04
source

2 answers

1

Use the aquire and release methods with a Semaphore object to block the read thread if it is being written and vice versa.

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.util.concurrent.Semaphore;

public class Ejercicio7 extends Thread

{      
    public static Semaphore mutex = new Semaphore(1, true);

    public static void main(String[] args) throws InterruptedException
    {
        Thread hilo1 = new Ejercicio7(); hilo1.setName("hilo1");
        Thread hilo2 = new Ejercicio7(); hilo2.setName("hilo2");

        hilo1.start();
        hilo2.start();
    }

    public void run()
    {

        if(Thread.currentThread().getName().equals("hilo1"))
        {
            grabarFicheroTexto();
        }

        else
        {           
            try {
                leerFicheroTexto();
            } catch (IOException e) {e.printStackTrace();}          
        }
    }

    public static void grabarFicheroTexto()
    {

        mutex.acquireUninterruptibly();
        char c;
        String contenido = "";
        try{
            System.out.println("Vas a escribir en un fichero de texto en Java\n");
            System.out.print("Escribe aqui: ");
            FileWriter fichero=new FileWriter("Archivo.txt");
            StringBuffer str=new StringBuffer();
            while (true){
                c=(char)System.in.read();
                if(c == ' ')
                    contenido = "";
                if(c == '\n')
                    if(contenido.trim().equalsIgnoreCase("fin"))
                        break;
                    else contenido = "";
                contenido += c;
                str.append(c);    
            }
            String cadena=new String(str); 
            cadena = cadena.replace("fin", "");
            fichero.write(cadena);          

            if (fichero!=null)
                fichero.close();
        }catch(IOException ex){}
        System.out.println("FICHERO ESCRITO CORRECTAMENTE");

        mutex.release();
    }
    public static void leerFicheroTexto()throws IOException
    {

        mutex.acquireUninterruptibly();

        System.out.println("Estas leyendo un fichero de texto en Java\n");
        FileReader fr = new FileReader("Archivo.txt");
        BufferedReader br = new BufferedReader(fr);
        String s;

        while((s = br.readLine()) != null) {
          System.out.println(s);
        }
        fr.close();  

        mutex.release();

    }
}

OUTPUT

    
answered by 11.11.2017 / 15:34
source
2

Use synchronized to synchronize access to the method.

This what it does is that if you are executing the method RecordTextFile () then the object will be blocked so that you can not access the inside of the %%% block from another thread until it finishes what will keep the execution synchronized.

To achieve this, create a static variable that will be the traffic between accessing one method or another and you use it within the synchronized block:

public class Ejercicio7 extends Thread
{       

   public static readonly Object lock = new Object();

    public static void main(String[] args)
    {
        Thread hilo1 = new Ejercicio7(); hilo1.setName("hilo1");
        Thread hilo2 = new Ejercicio7(); hilo2.setName("hilo2");

        hilo1.start();
        hilo2.start();
    }

    public void run()
    {
        if(Thread.currentThread().getName().equals("hilo1"))
        {
            grabarFicheroTexto();
        }
        else
        {           
            try {
                leerFicheroTexto();
            } catch (IOException e) {e.printStackTrace();}          
        }
    }

    public static void grabarFicheroTexto()
    {

        synchronized(lock)
        {
            char c;
            try{
                System.out.println("Vas a escribir en un fichero de texto en Java\n");
                System.out.print("Escribe aqui: ");
                FileWriter fichero=new FileWriter("..\Threads\src\ejercicio7\Archivo.txt");
                StringBuffer str=new StringBuffer();
                while ((c=(char)System.in.read())!='\n')
                    str.append(c);
                String cadena=new String(str);  
                fichero.write(cadena);          

                if (fichero!=null)
                    fichero.close();
            }catch(IOException ex){}
            System.out.println("FICHERO ESCRITO CORRECTAMENTE");

        }
    }
    public static void leerFicheroTexto()throws IOException
    {
        synchronized(lock){

            System.out.println("Estas leyendo un fichero de texto en Java\n");
            FileReader fr = new FileReader("..\Threads\src\ejercicio7\Archivo.txt");
            BufferedReader br = new BufferedReader(fr);
            String s;

            while((s = br.readLine()) != null) {
              System.out.println(s);
            }
            fr.close();
        }
    }
}
    
answered by 11.11.2017 в 15:24