Programma Due Thread File

di il
1 risposte

Programma Due Thread File

Ciao a tutti. Ho un problema con un programma.
Ci sono 2 thread, e un file che rimane aperto.
Il primo thread scrive delle linee di testo sul file, mentre il secondo thread le legge una ad una appena viene scritta ma non va mai in fase di sleep.
Quindi:
-Il file viene aperto
-il primo thread scrive la linea su file e non va mai in fase di sleep.
-Il secondo legge la linea appena viene scritta e non va mai in sleep.
-nessuno dei due file vanno mai in fase di sleep.
-e così via fino alla chiusura del file
Ringrazio anticipatamente chi riesca o provi a risolvere il problema.
( pensavo di usare il comando endoffile() per controllare se il primo thread ha scritto una nuova linea, però son in alto mare)

1 Risposte

  • Re: Programma Due Thread File

    Ciao, spero di aver capito bene, il tuo problema si risolve con il classico modello produttore-consumatore, hai un thread che scrive una linea su un file ed un altro che la deve leggere non appena pronta.Il file rappresenta la risorsa condivisa, i due thread devono essere sincronizzati su esso in modo tale che uno scriva quando l'ultima riga da lui scritta è stata letta e l'altro legga sempre una nuova riga non appena pronta.Per modellare la risorsa condivisa possiamo realizzare una classe di questo tipo

    public class Resource {

    private File file;
    private boolean finished;

    public File getFile() {
    return file;
    }
    public void setFile(File file) {
    this.file = file;
    }
    public boolean isFinished() {
    return finished;
    }
    public void setFinished(boolean finished) {
    this.finished = finished;
    }

    }

    che incapsula il file di scrittura/lettura ed un flag che indicherà al secondo thread(quello che legge)che il primo thread(quello che scrive) ha terminato la scrittura.La sincronizzazione dei due thread avviene attraverso l'acquisizione del lock su un oggetto Resource comune.In pratica quando il primo thread deve scrivere su file ,prima deve acquisire il lock sull'oggetto Resource che lo rappresenta, poi può scrivere.Stesso discorso per la lettura.Un volta che il primo thread ha scritto una riga,invoca notify() sull'oggetto resource per notificare il secondo thread in stato di attesa, rilascia il lock uscendo dal blocco synchronized , ed infine va in wait attendendo la notifica da parte del secondo thread per poter continuare la scrittura.
    Il secondo thread si comporta in modo analogo, legge, notifica e si pone in attesa della lettura di altri dati,in più controlla il campo finished della classe Resource per sapere se la scrittura dei dati è terminata.Ti scrivo i sorgenti di un possibile esempio(li ho fatti e provati velocemente ma spero ti siano di aiuto),questa demo scrive 20 righe su un file, un thread scrive una riga l'altro la legge subito :

    Thread1.java:

    import java.io.FileWriter;
    import java.io.IOException;
    import java.io.PrintWriter;


    public class Thread1 extends Thread {

    private Resource resource;

    public Thread1(Resource resource) {
    this.resource = resource;
    }

    public void run() {
    try {
    for (int i = 0; i < 20; i++) {

    synchronized (resource) {
    try {
    /*apertura file in append*/
    FileWriter fileWriter = new FileWriter(resource.getFile(), true);
    PrintWriter writer = new PrintWriter(fileWriter);

    System.out.println("THREAD1 writing " + "Line" + i);
    writer.println("Line" + i);
    writer.close();
    fileWriter.close();

    } catch (IOException ex) {
    throw new RuntimeException(ex);
    }

    resource.notify();

    if (i == 19) {
    /*scrittura terminata*/
    resource.setFinished(true);

    } else {
    /*scritta una riga, attesa per la lettura*/
    resource.wait();
    }
    }
    }
    } catch (InterruptedException e) {
    e.printStackTrace();
    }
    }
    }

    Thread2.java:

    import java.io.BufferedReader;
    import java.io.FileReader;
    import java.io.IOException;



    public class Thread2 extends Thread {

    private Resource resource;

    public Thread2(Resource resource) {
    this.resource = resource;
    }

    public void run() {
    try {
    boolean exit = false;
    while (!exit) {
    synchronized (resource) {
    FileReader reader = null;
    BufferedReader buff = null;

    reader = new FileReader(resource.getFile());
    buff = new BufferedReader(reader);

    String line;
    String output = "";
    /*recupero ultima riga*/
    while ((line = buff.readLine()) != null) {
    output = line;
    }

    System.out.println("Thread2 reading line:" + output);


    buff.close();
    reader.close();

    resource.notify();

    if (!resource.isFinished()) {
    resource.wait();
    } else {
    exit = true;
    }
    }
    }

    } catch (InterruptedException e) {
    e.printStackTrace();
    } catch (IOException io) {
    io.printStackTrace();
    }
    }
    }

    Main.java:

    import java.io.File;

    public class Main {

    public static void main(String[] args) {

    Resource resource = new Resource();
    resource.setFile(new File("c:\\File.txt"));

    Thread1 t1 = new Thread1(resource);

    t1.start();

    try {
    /*attesa di 2 secondi prima di lanciare il secondo thread*/
    Thread.currentThread().sleep(2000);
    } catch (InterruptedException ex) {
    ex.printStackTrace();
    }

    Thread2 t2 = new Thread2(resource);

    t2.start();

    try {
    /*attesa terminazione thread*/
    t1.join();
    t2.join();
    } catch (InterruptedException ex) {
    ex.printStackTrace();
    }

    }
    }

    L'output che dovresti ottenere è il seguente:

    THREAD1 writing Line0
    Thread2 reading line:Line0
    THREAD1 writing Line1
    Thread2 reading line:Line1
    THREAD1 writing Line2
    Thread2 reading line:Line2
    THREAD1 writing Line3
    Thread2 reading line:Line3
    THREAD1 writing Line4
    Thread2 reading line:Line4
    THREAD1 writing Line5
    Thread2 reading line:Line5
    THREAD1 writing Line6
    Thread2 reading line:Line6
    THREAD1 writing Line7
    Thread2 reading line:Line7
    THREAD1 writing Line8
    Thread2 reading line:Line8
    THREAD1 writing Line9
    Thread2 reading line:Line9
    THREAD1 writing Line10
    Thread2 reading line:Line10
    THREAD1 writing Line11
    Thread2 reading line:Line11
    THREAD1 writing Line12
    Thread2 reading line:Line12
    THREAD1 writing Line13
    Thread2 reading line:Line13
    THREAD1 writing Line14
    Thread2 reading line:Line14
    THREAD1 writing Line15
    Thread2 reading line:Line15
    THREAD1 writing Line16
    Thread2 reading line:Line16
    THREAD1 writing Line17
    Thread2 reading line:Line17
    THREAD1 writing Line18
    Thread2 reading line:Line18
    THREAD1 writing Line19
    Thread2 reading line:Line19
Devi accedere o registrarti per scrivere nel forum
1 risposte