How to read and write data into same file simultaneously

Vimal picture Vimal · Dec 13, 2011 · Viewed 10.7k times · Source

I have read many a posts where-in they speak about reading and writing into the file NOT simultaneously using JavaME. I have a special use case scenarios where-in my log file (maybe full file or just portion of the file) is uploaded to the server on regular basis. This must continue without hampering the current logging of the application in this same file.

The code sample is a under:

boolean writing = true;
boolean reading = true;
void main() {
    new Thread("THREAD-FILE-READ") {
        public void run() {
            InputStream instream = getFileInStream();
            if (null != instream) {
                while (reading) {
                    try {
                        try {
                            synchronized(READ_LOCK) {
                                READ_LOCK.wait();
                            }
                        } catch (InterruptedException ex) {
                            ex.printStackTrace();
                        }

                        if (writtenCharsLen > 0) {
                            byte[] bytes = new byte[writtenCharsLen];
                            instream.read(bytes, 0, writtenCharsLen);
                            System.out.println("Read="+new String(bytes));
                            bytes = null;
                            writtenCharsLen = 0;
                        }
                    } catch (IOException ioe) {
                        ioe.printStackTrace();
                    }
                }
            }
            closeStream(instream);
        }
    }.start();

    new Thread("THREAD-FILE-WRITE") {
        public void run() {
            OutputStream outstream = getFileOutStream();
            if (null != outstream) {
                while (writing) {
                    try {
                        byte[] str = randomString();
                        if (null != str) {
                            writtenCharsLen = str.length;
                            System.out.println("Write=" + new String(str));
                            outstream.write(str);
                            str = null;
                        }
                    } catch (IOException ex) {
                        ex.printStackTrace();

                    } finally {
                        notifyReadStream();
                    }

                    try {
                        synchronized(WRITE_LOCK) {
                            WRITE_LOCK.wait();
                        }
                    } catch (InterruptedException ex) {
                        ex.printStackTrace();
                    }
                }
            }
            closeStream(outstream );
        }
    }.start();

}

void notifyReadStream() {
    try {
        synchronized (READ_LOCK) {
            READ_LOCK.notify();
        }
    } catch (Exception e) {
        e.printStackTrace();
    }
}

void notifyWriteStream() {
    try {
        synchronized (WRITE_LOCK) {
            WRITE_LOCK.notify();
        }
    } catch (Exception e) {
        e.printStackTrace();
    }
}

In the above code I will replace sop-read and sop-write with proper calls to network IO methods.

PS: Since this piece of code will run of multiple files and multitude of devices i need the modification as compressed as possible to keep my runtime heap as low as possible. Also this piece of code will run till the application life cycle hence closing and opening the file in middle is out of consideration.

Present Undesired Result: The read and write threads are showing running sop's for read and write. The read thread is reading from the position the writing thread has written. I am not facing any exception in this code but the result is undesired. I have also tried synchronizing read and write streams but that is throwing IllegalMonitorStateException

Expected Result: Reading of the stream must be triggered after writing into the stream is completed, also the read thread must be able to read from any position in the file.

Any help / pointers is useful?

EDIT: I was able to synchronize the read and the write streams using different monitors but i still feel, i could have done better using single monitor. Will try it sometime later.

Answer

Tudor picture Tudor · Dec 13, 2011

I will attack this problem:

Present Undesired Result: The read and write threads are showing running sop's for read and write. The read thread is reading from the position the writing thread has written. I am not facing any exception in this code but the result is undesired. I have also tried synchronizing read and write streams but that is throwing IllegalMonitorStateException.

If you have synchronized the access using monitors i.e. the reader calls someObject.wait() and the writer calls someObject.notify(), remember that you have to wrap these calls in a synchronized block on someObject:

synchronized(someObject) {
    someObject.wait();
}


synchronized(someObject) {
    someObject.notify();
}

This is the cause for IllegalMonitorStateException.