Java 线程化,易失变量不升级

Java 线程化,易失变量不升级,java,multithreading,volatile,Java,Multithreading,Volatile,我环顾四周,发现类似的代码,但我的代码不起作用。我的可变变量在班级时钟中变化,但我的班级访客没有得到变化的变量。我将发布我的代码。如果有类似的问题,请链接。谢谢你的帮助 我尝试将所有类中的易失性布尔变量声明设置为false。这没用 public class Main { volatile static boolean isInSession; volatile static boolean sessionOver; public static void main (String [] args

我环顾四周,发现类似的代码,但我的代码不起作用。我的可变变量在班级时钟中变化,但我的班级访客没有得到变化的变量。我将发布我的代码。如果有类似的问题,请链接。谢谢你的帮助

我尝试将所有类中的易失性布尔变量声明设置为false。这没用

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);
}

}
公共类主{
易失性静态布尔isInSession;
易失性静态布尔sessionOver;
公共静态void main(字符串[]args)
{
对于(int i=0;i<25;i++){
访客=新访客(i,isInSession);
visitor.start();
}
线程时钟=新线程(新时钟(isInSession,sessionOver));
clock.start();
}
}
公共类访问者扩展线程{
易失性静态布尔isInSession;
私人内部访问;
挥发性静态积分=5;
访问者(int visotrId,布尔isInSession)
{
this.isInSession=isInSession;
设置名称(“visitorId”+visitorId);
}
@凌驾
公开募捐{
while(true)
{
while(isInSession){}
System.out.println(“访客登录登录”+登录登录登录);
如果(isInSession)
System.out.println(“访问者登录”+登录);
试一试{
Thread.currentThread().sleep(5000);
}
捕捉(中断异常e)
{ }
}
}
公共void消息(字符串m){
System.out.println(“[”+(System.currentTimeMillis()-time)+”]
“+getName()+”:“+m);
}
}
公共类时钟实现可运行{
易失性静态布尔isInSession;
易失性静态布尔sessionOver;
私有int会话=0;
公共时钟(布尔isInSession、布尔sessionOver)
{
this.isInSession=isInSession;
this.sessionOver=sessionOver;
}
@凌驾
公开募捐{
while(true)
{
试一试{
Thread.currentThread().sleep(5000);
}捕捉(中断异常e){
}
isInSession=false;
msg(“剧院开放”);
试一试{
Thread.currentThread().sleep(5000);
}捕捉(中断异常e){
}
isInSession=true;
//System.out.println(“时钟内isInSession”+isInSession);
会话++;
}
}//运行结束
公共void消息(字符串m){
System.out.println(“[”+(System.currentTimeMillis()-time)+”]“+”时钟:
“+m);
}
}
您可以根据自己的目的使用

正如JB Nizet所指出的,Java中的参数是按值传递的。这里有一个关于另一个的答案,详细解释了这一点

出于您的目的,只需知道,“当我们传递一个对象的值时,我们传递的是对它的引用”(引用自上面提到的SO帖子)。通过创建一个
AtomicBoolean
对象并将其传递给
Clock
Visitor
对象,当
Clock
更新
AtomicBoolean
的值时,
Visitor
对象也将收到更新的值

因此,您的主类应该如下所示:

公共类主{
静态AtomicBoolean isInSession=new AtomicBoolean();//默认值为false
静态AtomicBoolean sessionOver=新的AtomicBoolean();
公共静态void main(字符串[]args)
{
对于(int i=0;i<25;i++){
访客=新访客(i,isInSession);
visitor.start();
}
线程时钟=新线程(新时钟(isInSession,sessionOver));
clock.start();
}
}

要访问
Visitor
中的
AtomicBoolean
的值或更新
Clock
中的值,可以分别使用
get()
set(boolean)
方法。

参数在Java中按值传递。每个对象都有自己的布尔变量。改变一个不会神奇地改变所有其他。就像现实生活中一样:每辆车都有一种颜色。如果我把一辆车漆成红色,所有的车不会神奇地变成红色。即使是那些最初在同一工厂使用相同颜色绘制的,也不是。volatile并不意味着我有一个变量没有缓存在内存中。那么你建议如何处理易失性变量呢?这与易失性完全无关。再次说明:如果您使用
car1=新车(“红色”);Car car2=新车(“红色”);car1.设置颜色(“绿色”),则car1为绿色,car2仍为红色。它们使用两个单独的变量来保持颜色,更改一个变量不会更改另一个变量。无论您使用volatile还是多线程,都不会改变这一点:您有两个独立的变量。您的代码有3个独立的
isInSession
变量,每个变量都有自己的值:Main.isInSession、Visitor.isInSession和Clock.isInSession。@XavierMaldonado,此线程将帮助您了解volatile的用途。