如何处理2个线程使用的变量?

时间:2013-04-22 20:56:29

标签: java multithreading swing

一个线程继续读取从BufferedReader接收的字节。数据来自SerialPort

在主线程上,有JMenuItem点击时串口关闭,BufferedReader应该停止接收消息。

问题是:

如果我在读取消息时尝试关闭,应用程序将卡住,并且在端口停止发送消息之前串口不会关闭。

基本上,我应该在关闭串口之前关闭阅读器。如果我这样做,有时我得到一个空指针异常,因为我在阅读时关闭缓冲的阅读器。

我该如何解决这个问题?

2 个答案:

答案 0 :(得分:1)

听起来您可以在阅读器类中使用stop方法解决此问题(从菜单项的click事件中调用)

private boolean isStopped = false;

public void stop() {
    isStopped = true;
}

while(bufferedReader.isReady()) {
    bufferedReader.read();
    if(isStopped) {
        bufferedReader.close();
    }
}

这样您就可以确保在完成所有close来电之前不要致电read

答案 1 :(得分:0)

最简单的方法是创建一个将包裹BufferedReader的SynchronizedReader类。但是如果没有更多的上下文,我不能保证这会有效,特别是如果你有调用代码来对Reader进行多次相互依赖的调用(那么你需要确保所有调用都在一个synchronized(reader)中进行块)。

import java.io.IOException;
import java.io.Reader;
import java.nio.CharBuffer;

public class SynchronizedReader extends Reader {

    private Reader reader;

    public SynchronizedReader(Reader reader) {
        super();
        this.reader = reader;
    }

    @Override
    public synchronized int read(char[] cbuf, int off, int len) throws IOException {
        return reader.read(cbuf, off, len);
    }

    @Override
    public synchronized void close() throws IOException {
        reader.close();
    }

    @Override
    public synchronized int hashCode() {
        return reader.hashCode();
    }

    @Override
    public synchronized int read(CharBuffer target) throws IOException {
        return reader.read(target);
    }

    @Override
    public synchronized int read() throws IOException {
        return reader.read();
    }

    @Override
    public synchronized int read(char[] cbuf) throws IOException {
        return reader.read(cbuf);
    }

    @Override
    public synchronized boolean equals(Object obj) {
        return reader.equals(obj);
    }

    @Override
    public synchronized long skip(long n) throws IOException {
        return reader.skip(n);
    }

    @Override
    public synchronized boolean ready() throws IOException {
        return reader.ready();
    }

    @Override
    public synchronized boolean markSupported() {
        return reader.markSupported();
    }

    @Override
    public synchronized void mark(int readAheadLimit) throws IOException {
        reader.mark(readAheadLimit);
    }

    @Override
    public synchronized void reset() throws IOException {
        reader.reset();
    }

    @Override
    public synchronized String toString() {
        return reader.toString();
    }

}