变量var的值始终为0. IT几乎就像从未调用过该方法一样。我希望能够从线程内部更改val的值,如果我调用getVal(),我希望能够访问新值。
public class Test1 {
private int val;
public Test1() {
val=0;
}
public void changeVal() {
new Thread(new Runnable() {
public void run() {
val=1;
}
}).start();
}
public int getVal() {
return this.val;
}
public static void main(String[]args) {
Test1 x=new Test1();
x.changeVal();
System.out.println("VAl: "+x.getVal() );
}
}
答案 0 :(得分:3)
值已更改,但getVal()(在大多数情况下)在方法' run'中var = 1之前执行。执行顺序由线程调度程序控制,但正如Johnny Mopp所述,添加.join()将修复它。
public void changeVal() throws InterruptedException {
Thread t = new Thread(new Runnable() {
@Override
public void run() {
val = 1;
}
});
t.start();
t.join();
}
public static void main(String[] args) throws InterruptedException {
Test1 x = new Test1();
x.changeVal();
System.out.println("VAl: " + x.getVal());
}
答案 1 :(得分:0)
您已在声明
之间设置竞争条件 x.changeVal();
和
System.out.println("VAL: "+x.getVal() );
尝试将以下代码放在上述两个语句之间。
try {
Thread.sleep(100);
}
catch (Exception e) {
System.out.println("Exception: " + e);
}
这使您的新线程有机会在到达println语句之前建立。
答案 2 :(得分:0)
您需要更改主要方法,如下所示:
public static void main(String[]args)
{
Test1 x=new Test1();
x.changeVal();
try {
Thread.sleep(100);//sometime here
}
catch (Exception e) {
System.out.println("Exception: " + e);
}
System.out.println("VAl: "+x.getVal() );
}
或
您可以使用Thread.join();
在changeVal()
方法中使用子线程加入主线程。
答案 3 :(得分:0)
一个灵魂可以使用ReentrantLock
将其定义为类成员变量
Lock lock = new ReentrantLock();
在changeVal中使用此锁
public void changeVal() throws InterruptedException {
if (lock.tryLock()) {
try {
new Thread(new Runnable() {
@Override
public void run() {
val = val + 1;
}
}).start();
} finally {
lock.unlock();
}
}
}
答案 4 :(得分:-1)
您需要创建变量volatile
,如果您希望在main方法中打印变量之前更改变量,则需要安排一些同步或锁定。这使线程毫无意义。
很难看出其中的任何一点。