简体   繁体   中英

One thread updates variable and another read it, do I need something special

I have a class that has the object "Card". This class keeps checking to see if the object is not null anymore. Only one other thread can update this object. Should I just do it like the code below? Use volatile?Syncronized? lock (which I dont know how to use really)? What do you recommend as easiest solution?

Class A{

 public Card myCard = null;


 public void keepCheck(){

    while(myCard == null){
       Thread.sleep(100)
    }
    //value updated
     callAnotherMethod();
 }

Another thread has following:

public void run(){
     a.myCard = new Card(5);
 }

What do you suggest?

如果要轮询从另一个线程进行修改,则该变量需要是可变的,但是更好的解决方案是使用wait() / notify()Semaphore来使其他线程保持睡眠状态,直到初始化myCard变量为止。

Looks like you have a classic producer/consumer case.

You can handle this case using wait()/notify() methods. See here for an example: How to use wait and notify in Java?

Or here, for more examples: http://www.programcreek.com/2009/02/notify-and-wait-example/

You should use a proper wait event (see the Guarded Block tutorial), otherwise you run the risk of the "watching" thread seeing the reference before it sees completely initialized member fields of the Card . Also wait() will allow the thread to sleep instead of sucking up CPU in a tight while loop.

For example:

Class A {

    private final Object cardMonitor = new Object();
    private volatile Card myCard;

    public void keepCheck () {
        synchronized (cardMonitor) {
            while (myCard == null) {
                try {
                    cardMonitor.wait();
                } catch (InterruptedException x) {
                    // either abort or ignore, your choice
                }
            }
        }
        callAnotherMethod();
    }

    public void run () {
        synchronized (cardMonitor) {
            myCard = new Card(5);
            cardMonitor.notifyAll();
        }
    }

}

I made myCard private in the above example. I do recommend avoiding lots of public fields in a case like this, as the code could end up getting messy fast.

Also note that you do not need cardMonitor -- you could use the A itself, but having a separate monitor object lets you have finer control over synchronization.

Beware, with the above implementation, if run() is called while callAnotherMethod() is executing, it will change myCard which may break callAnotherMethod() (which you do not show). Moving callAnotherMethod() inside the synchronized block is one possible solution, but you have to decide what the appropriate strategy is there given your requirements.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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