我尝试了以下操作并且无效:
“开始”课程:
public class Start implements Runnable {
Start start;
LoadExample loadExample;
Thread mainThread;
Thread loadExampleThread;
private boolean running = false;
public static boolean isExampleLoaded = false;
public static void main(String[] args) {
begin = new Start();
loadExample = new LoadExample();
begin.start();
}
public synchronized void start() {
mainThread = new Thread(this, "Main");
mainThread.start();
loadExampleThread = new Thread(loadExample, "Load Example");
loadExampleThread.start();
}
public void run() {
running = true;
while (running) {
if(isExampleLoaded){
System.out.println("Loaded!");
}
}
}
}
“LoadExample”类:
public class LoadExample implements Runnable {
public void run(){
//blabla, loading if you will...
Start.isExampleLoaded = true;
}
}
您可能会在上面的代码中发现语法错误,但这只是因为我在没有签入Eclipse的情况下输入了这个错误。我的原始代码非常相似,Eclipse没有显示任何错误或警告。
我的问题是代码不会打印“已加载!”。 我认为这是因为(1)线程无法更改静态变量或其他类的变量,或者(2)更改只是更新当前线程而不是其他(s),但我可能错了。
任何澄清都表示赞赏。
修改
如果您发现上述任何错误,请告诉我,我会尽快更新。
答案 0 :(得分:6)
您需要标记变量volatile
才能使此示例正常工作。如果没有volatile
,读取线程将读取isExampleLoaded
一次,而不再读取它,因为编译器知道该变量尚未写入。
答案 1 :(得分:1)
每当您想要从多个线程访问变量时,所有对该变量的访问都应该在synchronized
块或方法中,所有这些都使用相同的监视器。在本程序中,如果您制作了静态同步isExampleLoaded()
和setExampleLoaded()
方法,并在任何地方使用这些方法,该程序将起作用。
正如@dasblinkenlight指出的那样,也可以将变量标记为volatile
,这也可以。 volatile
不能扩展到许多变量或许多线程。在一般情况下,synchronized
访问权限是更好的解决方案。