Java:如何使用synchronized和volatile

时间:2013-01-28 19:39:04

标签: java multithreading synchronized volatile

我有两个主题。第一个线程调用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;
    }
}

3 个答案:

答案 0 :(得分:7)

我不是在这里使用synchronized volatile,而是亲自使用AtomicInteger

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正在... ...

答案 1 :(得分:1)

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

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

答案 2 :(得分:0)

  

Volatile变量仅保证变量和顺序的可见性   代码到线程。但它不提供线程设施   对方法的所有权。 Synchronized关键字让线程拥有   synchronized方法的所有权。

通过您的查询:

  

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

取决于你想要什么。如果你想在Thread1调用getX之后调用Thread2 setX,那么你需要同步这些方法,但是你也必须使用wait()notify()方法。

  

我还可以用第二个类来解决我的线程问题   volatile变量?

同样,这取决于你想要什么。如果您希望Thread2调用getX方法而不关心其他setX调用的Thread方法,那么您应该使用volatile,以便Thread2可以获得最新值{ {1}}。