线程,易失性变量不更新
Threading, volatile variable not updagting
我环顾四周,似乎有类似的代码,但我的代码不起作用。我的 volatile 变量在 class 时钟中变化,但我的 class 访问者没有得到改变的变量。我将 post 我的代码。如果有类似的问题请link。谢谢你的帮助。
我尝试将所有 classes 中的易失性布尔变量的声明设置为 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);
}
}
您可以根据自己的目的使用 AtomicBoolean。
正如 JB Nizet 所指出的,Java 中的参数是按值传递的。这是另一个 SO post 上的答案,详细解释了这一点。
为了您的目的,知道 "when we pass the value of an object, we are passing the reference to it"(上面提到的 SO post 的引述)就足够了。通过创建一个 AtomicBoolean
对象并将其传递给 Clock
和 Visitor
对象,当 Clock
更新 AtomicBoolean
的值时, Visitor
对象也将收到更新后的值。
因此,您的主要 class 应该如下所示:
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();
}
}
要访问 Visitor
中 AtomicBoolean
的值或更新 Clock
中的值,您可以使用 get()
和 set(boolean)
方法分别。
我环顾四周,似乎有类似的代码,但我的代码不起作用。我的 volatile 变量在 class 时钟中变化,但我的 class 访问者没有得到改变的变量。我将 post 我的代码。如果有类似的问题请link。谢谢你的帮助。
我尝试将所有 classes 中的易失性布尔变量的声明设置为 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);
}
}
您可以根据自己的目的使用 AtomicBoolean。
正如 JB Nizet 所指出的,Java 中的参数是按值传递的。这是另一个 SO post 上的答案,详细解释了这一点。
为了您的目的,知道 "when we pass the value of an object, we are passing the reference to it"(上面提到的 SO post 的引述)就足够了。通过创建一个 AtomicBoolean
对象并将其传递给 Clock
和 Visitor
对象,当 Clock
更新 AtomicBoolean
的值时, Visitor
对象也将收到更新后的值。
因此,您的主要 class 应该如下所示:
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();
}
}
要访问 Visitor
中 AtomicBoolean
的值或更新 Clock
中的值,您可以使用 get()
和 set(boolean)
方法分别。