5

我有两个线程。第一个线程调用 setX 方法,第二个线程调用 getX 方法。尽管我只有一个写作线程,但我是否必须将方法设置为同步?我也可以用第二类和 volatile 变量解决我的线程问题吗?

public class Test {
    private int x;  

    public synchronized  void setX(int x) {
        this.x = x;
    }

    public synchronized  int getX() {
        return this.x;
    }
}

public class Test2 {
    private volatile int x; 

    public void setX(int x) {
        this.x = x;
    }

    public int getX() {
        return this.x;
    }
}
4

3 回答 3

7

我个人不会使用synchronized or ,而是使用:volatileAtomicInteger

public class Test {
    private final AtomicInteger x = new AtomicInteger();  

    public void setX(int value) {
        x.set(value);
    }

    public int getX() {
        return x.get();
    }
}

(请注意,我还修复了您的get/ set- 之前您getX的设置,而您setX正在获取...)

于 2013-01-28T19:42:35.857 回答
1

要回答您的问题,是的,您需要某种形式的同步。由于您的共享状态是单个变量,并且此变量的类型为int,因此写入将是原子的(如果变量是 long 或 double 则不是这种情况)。但是您仍然需要同步以确保您没有可见性问题:线程 A 可以写入变量,而线程 B 看不到写入的值,而是看到前一个值。

在这种情况下,可以使用 synchronized、volatile 或 AtomicInteger 来实现同步。所有这些技术将确保写入对变量的任何后续读取都是可见的。

于 2013-01-28T19:46:45.253 回答
0

Volatile变量只保证变量对线程的可见性和代码顺序。但它没有为线程提供方法所有权的便利。Synchronized关键字让线程拥有synchronized方法的所有权。

按照您的查询:

第一个线程调用setX方法,第二个调用方法。尽管我只有一个写入线程,但我必须getX 设置方法吗?synchronized

取决于你想要什么。如果您希望 Thread2getX仅在Thread1 调用之后调用setX,那么是的,您需要同步方法,但是您还必须使用wait()andnotify()方法。

我也可以用第二类和 volatile变量解决我的线程问题吗?

同样,这取决于您想要什么。如果您希望您的 Thread2 调用getX方法而不关心setX其他调用的方法,Thread那么您应该使用volatileThread2 可以获取最新的x.

于 2013-01-28T19:58:06.513 回答