简体   繁体   中英

Threading, volatile variable not updagting

I looked around and seemed similar code but mine is not working. My volatile variable is chaning in the class clock but my class vistor is not getting the changed variable. I will post my code. If theres a similar queston please link. Thank you for the help.

I tried by setting the declarations in all my classes for the volatile boolean variables to false. It didn't help.

public class Main {
volatile static boolean isInSession;
volatile static boolean sessionOver;

public static void main (String [] args)
{
    for (int i = 0; i < 25; i++) {
        Visitor visitor = new Visitor(i, isInSession);
        visitor.start();
    }
    Thread clock = new Thread(new Clock(isInSession, sessionOver));
    clock.start();

}



}



public class Visitor extends Thread {


volatile static boolean isInSession;
private int visitorId;
volatile static int seats = 5;

Visitor(int visotrId, boolean isInSession)
{
    this.isInSession = isInSession;
    setName("visitorId " + visitorId);

}
@Override
public void run() {

    while(true)
    {
        while(isInSession){}

        System.out.println("In visitor isInSession " + isInSession);

        if(isInSession)
            System.out.println("Visitor isInSession " + isInSession);

        try {
            Thread.currentThread().sleep(5000);
        }
        catch(InterruptedException e)
        { }

    }
}
public void msg(String m) {
System.out.println("["+(System.currentTimeMillis()-time)+"] 
"+getName()+": "+m);
}


}


public class Clock implements Runnable  {

volatile static boolean isInSession;
volatile static boolean sessionOver;
private int session = 0;

public Clock(boolean isInSession, boolean sessionOver)
{
    this.isInSession = isInSession;
    this.sessionOver = sessionOver;

}

@Override
public void run() {
    while(true)
    {
        try {
            Thread.currentThread().sleep(5000);
        } catch (InterruptedException e) {
        }
        isInSession = false;

        msg("Theater is open");

        try {
            Thread.currentThread().sleep(5000);
        } catch (InterruptedException e) {
        }

        isInSession = true;
        //System.out.println("In clock isInSession " + isInSession);


        session++;
    }
}// end of run

    public void msg(String m) {
    System.out.println("["+(System.currentTimeMillis()-time)+"]" +"Clock: 
    "+  m);
}

}

You can use AtomicBoolean for your purpose.

As JB Nizet has pointed out, arguments in Java are passed-by-value. Here's an answer on another SO post that explains this in detail.

For your purpose, it suffices to know that, "when we pass the value of an object, we are passing the reference to it" (a quote from the SO post mentioned above). By creating an AtomicBoolean object and passing it to both the Clock and Visitor objects, when Clock updates the value of the AtomicBoolean , the Visitor objects will receive the updated value too.

So, your main class should look like this:

public class Main {
    static AtomicBoolean isInSession = new AtomicBoolean(); // default value is false
    static AtomicBoolean sessionOver = new AtomicBoolean();

    public static void main (String [] args)
    {
        for (int i = 0; i < 25; i++) {
            Visitor visitor = new Visitor(i, isInSession);
            visitor.start();
        }
        Thread clock = new Thread(new Clock(isInSession, sessionOver));
        clock.start();
    }
}

To access the value of the AtomicBoolean in Visitor or to update the value in Clock , you can use the get() and set(boolean) method respectively.

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