线程,volatile变量不更新

问题描述 投票:1回答:1

我环顾四周,似乎有类似的代码但是我的工作没有用。我的volatile变量是在类时钟中进行转换,但是我的类vistor没有获得更改的变量。我会发布我的代码。如果有类似的问题请链接。感谢您的帮助。

我尝试将所有类中的声明设置为volatile布尔变量为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);
}

}
java multithreading volatile
1个回答
1
投票

您可以使用AtomicBoolean达到您的目的。

正如JB Nizet指出的那样,Java中的参数是按值传递的。这是另一个SO post的答案,详细解释了这一点。

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

所以,你的主类应该是这样的:

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

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

© www.soinside.com 2019 - 2024. All rights reserved.