简体   繁体   English

Java:如何使用synchronized和volatile

[英]Java: How to use synchronized and volatile

I have two threads. 我有两个主题。 The first thread calls the setX method, the second one calls the getX method. 第一个线程调用setX方法,第二个线程调用getX方法。 Do I have to set the methods synchronized although i have only one writing thread? 我是否必须将方法设置为同步,尽管我只有一个写线程? And can i also solve my thread problem with the second class and the volatile variable? 我可以用第二类和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;
    }
}

Rather than use synchronized or volatile here, I'd personally use AtomicInteger : 我不是在这里使用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();
    }
}

(Note that I've also fixed your get / set - previously your getX was setting, and your setX was getting...) (请注意,我还修复了你的get / set - 之前你的getX正在设置,而你的setX正在......)

To answer your question, yes, you need some form of synchronization. 要回答您的问题,是的,您需要某种形式的同步。 Since your shared state is a single variable, and this variable is of type int , a write will be atomic (it would not be the case if the variable was a long or a double). 由于您的共享状态是单个变量,并且此变量的类型为int ,因此write将是原子的(如果变量是long或double,则不是这种情况)。 But you still need synchronization to make sure that you have no visibility problem: thread A could write to the variable, and thread B could not see the written value, but a previous one. 但是你仍然需要同步来确保你没有可见性问题:线程A可以写入变量,而线程B看不到写入的值,而是前一个。

The synchronization can be implemented using synchronized, volatile, or an AtomicInteger in this case. 在这种情况下,可以使用synchronized,volatile或AtomicInteger来实现同步。 All these techniques will ensure that the write will be visible to any subsequent read of the variable. 所有这些技术将确保写入对变量的任何后续读取都是可见的。

Volatile variable only guarantees the visibility of variable and order of codes to the Threads. Volatile变量仅保证变量和代码顺序对线程的可见性。 But it doesnot provide threads the facility of ownership on method. 但它并没有为线程提供方法所有权的便利。 Synchronized keyword let the threads to have ownership on the synchronized methods. Synchronized关键字允许线程拥有synchronized方法的所有权。

Going by your Query: 通过您的查询:

The first thread calls the setX method, the second one calls the getX method.Do I have to set the methods synchronized although i have only one writing thread? 第一个线程调用setX方法,第二个线程调用getX方法。虽然我只有一个写线程,但我必须设置方法synchronized吗?

Depending upon what you want. 取决于你想要什么。 If you want that Thread2 call getX only after Thread1 calls setX then yes you need to synchronize the methods but then you would have to use wait() and notify() methods also. 如果你想在Thread1调用setX之后才调用getX ,那么你需要同步方法,但是你也必须使用wait()notify()方法。

can i also solve my thread problem with the second class and the volatile variable? 我可以用第二类和volatile变量解决我的线程问题吗?

Again , it depends upon what you want. 同样,这取决于你想要什么。 If you wish your Thread2 to call getX method without concerning about setX method called by other Thread then you should use volatile so that Thread2 could get up to date value of x . 如果你希望你的Thread2调用getX方法而不关心其他Thread调用的setX方法那么你应该使用volatile这样Thread2可以获得x最新值。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM