Взаимная блокировка Java

 
 
 
Сообщения:3
Задание: Разработать программу, которая позволяла бы работать с тремя файлами. Исходная информация должна хранить в файле file1.txt (программа ее считывает и осуществляет с ней преобразования), затем преобразованная информация записывается в файл file2.txt, а в файл file3.txt программа должна записать исходную и преобразованную информацию.Оформить работу программы как работу двух подсистем, которые могут выполняться одновременно.
Реализовал:

import java.io.*;
import java.util.ArrayList;


//Контейнер для взаимодействия читателя и писателя
public class FileSystem {

    //Флаг для Писателя(Писатель не может писать, пока Читатель читает)
    private boolean read;
    //Флаг для Читателя(Читатель не может чиатать, по Писатель пишут)
    private boolean write;
    private File file1;
    private File file2;
    private File file3;

    public boolean isRead() {
        return read;
    }

    public void setRead(boolean read) {
        this.read = read;
    }

    public File getFile1() {
        return file1;
    }

    public void setFile1(File file1) {
        this.file1 = file1;
    }

    public File getFile2() {
        return file2;
    }

    public void setFile2(File file2) {
        this.file2 = file2;
    }

    public File getFile3() {
        return file3;
    }

    public void setFile3(File file3) {
        this.file3 = file3;
    }

    private ArrayList<Flower> arrayList;

    public FileSystem() throws IOException {

        this.setRead(false);
        this.setFile1(new File("File1.txt"));
        this.setFile2(new File("File2.txt"));
        this.setFile3(new File("File3.txt"));
        this.arrayList = new ArrayList<>();

        Flower flower1 = new Flower("Роза","Красная",14);
        Flower flower2 = new Flower("Тюльпан","Желтый",10);
        ArrayList<Flower> inishArrayList = new ArrayList<>();
        inishArrayList.add(flower1);inishArrayList.add(flower2);
        PrintWriter out = new PrintWriter(this.getFile1().getAbsoluteFile());
        for(int i =0; i < inishArrayList.size(); i++)
        {
            out.println(inishArrayList.get(i).getNameFlower());
            out.println(inishArrayList.get(i).getColorFlower());
            out.println(inishArrayList.get(i).getLengthFlower());
        }
        out.close();

        //Проверка
        ArrayList<String> Test = new ArrayList<String>();
        try {
            BufferedReader reader = new BufferedReader(new FileReader(this.getFile1()));
            String line;
            while ((line = reader.readLine()) != null) {
                Test.add(line);
            }
        } catch(IOException e) {
            throw new RuntimeException(e);
        }
        System.out.println(Test.size());
        ArrayList<Flower> fw = new ArrayList<Flower>();
        for(int i = 0; i<Test.size();i+=3)
        {
            Flower f = new Flower();
            f.setNameFlower(Test.get(i));
            f.setColorFlower(Test.get(i+1));
            f.setLengthFlower(Integer.parseInt(Test.get(i+2)));
            fw.add(f);
        }
        System.out.println(fw.size());
    }

    public synchronized void AddArray(ArrayList<Flower> temp) {

        this.arrayList = temp;

        //Пока пользователь не считает из массива
        while (this.isRead() != true)
        {
            //Поток спит
            try {
                wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        //Поток просыпается
        notify();
    }


    public ArrayList<Flower> getArrayList() {
      return this.arrayList;
    }

}

//Читатель читает из массива и сохраняет в файлы
class Reader implements Runnable{

    private FileSystem fileSystem;
    //Флаг для определения, в какой файл будет идти запись
    private int i;

    public Reader(FileSystem FS) {
        this.fileSystem = FS;
        this.i =0;
    }

    @Override
    public void run() {
        switch (i)
        {
            //Если данные первый раз записываются, то запись идет в 1 файл
            case 0:
            {
                PrintWriter out = null;
                try {
                    out = new PrintWriter(fileSystem.getFile3().getAbsoluteFile());
                } catch (FileNotFoundException e) {
                    e.printStackTrace();
                }
                for(int i =0; i < fileSystem.getArrayList().size(); i++)
                {
                    out.println(fileSystem.getArrayList().get(i).getNameFlower());
                    out.println(fileSystem.getArrayList().get(i).getColorFlower());
                    out.println(fileSystem.getArrayList().get(i).getLengthFlower());
                }
                out.close();
                this.fileSystem.setRead(true);
                i++;
            }
                break;
            //Если данные записываются второй раз, то запись идет в 2 файла
            case 1:
            {
                PrintWriter out = null;
                PrintWriter out2 = null;
                try {
                    out = new PrintWriter(fileSystem.getFile3().getAbsoluteFile());
                    out2 = new PrintWriter(fileSystem.getFile2().getAbsoluteFile());
                } catch (FileNotFoundException e) {
                    e.printStackTrace();
                }
                for(int i =0; i < fileSystem.getArrayList().size(); i++)
                {
                    out.println(fileSystem.getArrayList().get(i).getNameFlower());
                    out.println(fileSystem.getArrayList().get(i).getColorFlower());
                    out.println(fileSystem.getArrayList().get(i).getLengthFlower());
                }
                for(int i =0; i < fileSystem.getArrayList().size(); i++)
                {
                    out2.println(fileSystem.getArrayList().get(i).getNameFlower());
                    out2.println(fileSystem.getArrayList().get(i).getColorFlower());
                    out2.println(fileSystem.getArrayList().get(i).getLengthFlower());
                }
                out.close();
                out2.close();
                this.fileSystem.setRead(true);
                i++;
            }
            break;
        }
    }
}

//Писатель записывает и изменяет данные в список для читателя
class Writer implements Runnable{

    //Ссылка на общую систему с читателем
    private FileSystem fileSystem;
    //Флаг для определения, какой массив должен быть добавлен в системy
    private int i;

    public Writer(FileSystem FS)
    {
        this.fileSystem = FS;
        this.i = 0;
    }

    @Override
    public void run() {

        ArrayList<Flower> fw = null;

        switch (i) {
            //Если поток работает первый раз, то данные из файла поступают в массив системы
            case 0: {
                //Проверка
                ArrayList<String> Test = new ArrayList<String>();
                try {
                    BufferedReader reader = new BufferedReader(new FileReader(fileSystem.getFile1()));
                    String line;
                    while ((line = reader.readLine()) != null) {
                        Test.add(line);
                    }
                } catch(IOException e) {
                    throw new RuntimeException(e);
                }
                System.out.println(Test.size());
                fw = new ArrayList<Flower>();
                for(int i = 0; i<Test.size();i+=3)
                {
                    Flower f = new Flower();
                    f.setNameFlower(Test.get(i));
                    f.setColorFlower(Test.get(i+1));
                    f.setLengthFlower(Integer.parseInt(Test.get(i+2)));
                    fw.add(f);
                }
                System.out.println(fw.size());
                i++;
                this.fileSystem.AddArray(fw);
            }
            break;
            //Если данные уже были считаны из файла, и уже были в массиве, то
            //меняем данные и отправляем в массив
            case 1: {
                for (int i = 0; i < fw.size(); i++) {
                    fw.get(i).setNameFlower("Ромашка");
                    fw.get(i).setColorFlower("Cиний");
                }
                i++;
                this.fileSystem.AddArray(fw);
            }
            break;
        }

    }
}



Start.java:

import java.io.IOException;

public class Start {
    public static void main(String args[]) throws IOException {
        FileSystem fs = new FileSystem();
        Writer writer = new Writer(fs);
        Reader reader = new Reader(fs);
        new Thread(writer).start();
        new Thread(reader).start();
        return;
    }
}

Я так понимаю, что у меня получилось deadlock, так как во второй файл ничего не записывается и программа не завершается. Как исправить?
 
 
Сообщения:3
Проблема:
Второй поток захватывает монитор и сохраняет данные в файл, но потом не засыпает, тем самым не давая первому потоку выполнить манипуляцию с данными и уснуть.Не могу придумать, как это реализовать, чтобы и 2 поток спал.
 
Модераторы:Нет
Сейчас эту тему просматривают:Нет