如何同时读取和写入同一文件中的数据

时间:2011-12-13 00:50:48

标签: java multithreading java-me midp

我已经阅读了许多帖子,他们在这里发表了关于使用JavaME同时阅读和写入文件 NOT 的信息。我有一个特殊的用例场景,其中我的日志文件(可能是完整文件或只是文件的一部分)定期上传到服务器。这必须继续,而不会妨碍当前在同一文件中记录应用程序。

代码示例位于:

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();
    }
}

在上面的代码中,我将用适当的网络IO方法调用替换sop-read和sop-write。

PS:由于这段代码将运行多个文件和多个设备,我需要尽可能压缩修改,以使我的运行时堆尽可能低。此代码也将运行到应用程序生命周期,因此关闭并打开中间的文件是不可考虑的。

目前不受欢迎的结果: 读写线程显示正在运行的read和write。读取线程从写入线程写入的位置读取。我没有在此代码中遇到任何异常,但结果是不希望的。我也尝试过同步读写流,但这就是抛出IllegalMonitorStateException

预期结果 写入流完成后必须触发流的读取,读取线程也必须能够从文件中的任何位置读取。

任何帮助/指针都有用吗?

编辑:我能够使用不同的显示器同步读取和写入流但我仍然觉得,我可以使用单个显示器做得更好。稍后会尝试一下。

2 个答案:

答案 0 :(得分:1)

我会解决这个问题:

显示不需要的结果:读写线程显示正在运行的读写写入。读取线程从写入线程写入的位置读取。我没有在此代码中遇到任何异常,但结果是不希望的。我也尝试过同步读写流,但这就是抛出IllegalMonitorStateException

如果您已使用监视器同步访问权限,即读者调用someObject.wait()并且编写者调用someObject.notify(),请记住您必须在someObject上的同步块中包装这些调用:< / p>

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


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

这是IllegalMonitorStateException的原因。

答案 1 :(得分:0)

您的第一个问题是您在写入数据之前设置了writCharsLen。如果您的读线程在写线程实际写入之前看到它非零,那么您就会遇到问题。写入后移动writtenCharsLen = str.length。

我在您的示例中看到的另一个问题是线程永远不会产生控制。他们将是CPU生猪。