desiredHealth < p.getFakeHealth()
为真,它就有可能。
@Override
public void run(){
while(game_running){
System.out.println("asd");
if(desiredHealth < player.getFakeHealth()){
DOES SOMETHING
}
}
但是......没有'System.out'它不起作用。它不检查条件。 它在某种程度上是低优先级,或者其他什么。
@Override
public void run(){
while(game_running){
if(desiredHealth < player.getFakeHealth())
DOES SOMETHING
}
}
我是线程的新手,所以请不要对我大喊:)
仅仅是为了获取信息,这个线程是一个普通的类,它“扩展了线程”,是的 - 它正在运行。 “game_running”也一直都是真的。
答案 0 :(得分:4)
变量必须是volatile,因为volatile关键字表示值可能会在不同的访问之间发生变化,即使它似乎没有被修改。
因此,请确保game_running
已声明为volatile
。
答案 1 :(得分:1)
<强>说明:强> 啊,我在一个较老的SO问题上看过这个。我会尝试找到它以获取更多信息。
您的问题正在发生,因为输出流的print正在阻塞当前线程,desiredHealth
和player.getFakeHealth()
表达式之一获得第二次机会被其他线程评估/更改voilà !魔术发生了。这是因为printf
上的glibc
已同步,因此在您打印时,其余操作正在等待println
操作完成。
解决:强>
我们没有足够的上下文(谁正在初始化播放器,谁进行更改等等),但很明显你有一个线程问题,某些东西没有正确同步,你的后台线程使用坏值。其中一个原因可能是某些变量不是volatile
,如果后台线程读取缓存值,则表明您已经遇到问题。
答案 2 :(得分:1)
关于并发性需要研究的一个主题是Java memory model(这是官方规范,但我建议你阅读一本教程或一本好书,因为规范对于初学者来说相当复杂)
当不同的线程使用相同的内存时(使用相同的变量 - 例如当一个人写入变量,另一个根据他们的值做出决策时)的一个问题是出于优化原因,一个人写的值另一方并不总是看到线程。
例如,一个线程可以在一个CPU上运行,并且该变量被加载到该CPU中的寄存器中。如果需要一直将其写回主存储器,则会降低处理速度。因此它在该寄存器中操作它,并且只在必要时才将其写回内存。但是如果另一个线程期望看到第一个线程正在编写的值呢?
在这种情况下,在它们被回写之前它不会看到它们,这可能永远不会发生。
有几种方法可以确保写入操作被“提交”#34;在另一个线程需要使用它们之前的内存。一种是使用同步,另一种是使用volatile
关键字。
System.out.println()
实际上包含一个同步操作,因此它可能会导致这些变量被提交到内存,从而使线程能够看到更新后的值。
将变量声明为volatile
意味着所有其他线程立即看到其中的任何更改。因此,使用volatile
变量也是确保看到它们的一种方式。
用于决定是否保持线程运行的变量通常应该声明为volatile
。但是,在您的情况下,变量desiredHealth
(如果它由不同的线程编写)和任何变量getFakeHealth()
依赖(如果它们由不同的线程编写)应该是易变的或以其他方式同步。
最重要的是,无论两个线程之间共享的信息需要同步还是至少使用volatile
。可以不分享未共享的信息。