这是在java中使用volatile变量的好例子吗?

时间:2018-06-19 09:59:42

标签: java

我有一个线程,它监听来自服务器的传入字符串流。我有一个类,我将传入的字符串设置为:

public class StreamData {

    protected static volatile String INCOMING_STRING = null;

    public static String getIncomingString() {
        return INCOMING_STRING;
    }

    public static void setIncomingString(String IncomingString) {
        INCOMING_STRING = IncomingString;
    }
}

所以在我Thread1 setIncomingString(String IncomingString) Thread2 现在我有另一个线程getIncomingString(),它通过先调用<Route exact path ="/Messages/:id" component={Message} /> 来监听客户端请求并发回数据。

我在这里使用volatile的原因是因为我在两个线程之间共享数据而且我读到了在这种情况下应该使用volatile变量。我的想法是否正确?

2 个答案:

答案 0 :(得分:2)

从某种意义上讲,这是安全的。调用getIncomingString的帖子可以保证看到最近通过调用setIncomingString写的字符串。

然而......

目前尚不清楚此属性是否足以使StreamData有用。例如:

  1. Thread1收到一个字符串并调用setIncomingString
  2. Thread1收到第二个字符串并再次调用setIncomingString
  3. Thread2调用getIncomingString ...并获取第二个字符串。
  4. 在上面的序列中,第一个字符串已经丢失,并且两个线程都没有意识到这一点。

    StreamData类不允许您“流式传输”数据。要实现 ,您需要的是类似于经典队列类的地方:

    • 一个线程添加字符串,第二个线程删除它们,
    • 第一个线程阻塞队列是否太满,
    • 如果队列为空,则第二个线程阻塞,
    • 两个线程都不必执行“忙循环”等待事情发生。

    仅使用volatile无法实现。

答案 1 :(得分:0)

是的,这应该是线程保存。单个对象{(1 {})和volatile操作上的static足以防止多线程问题。请参阅this question以清除您对set属性和线程保存操作的理解。