Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/309.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/node.js/42.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java错误的优化_Java - Fatal编程技术网

Java错误的优化

Java错误的优化,java,Java,我有这个密码 while(!decks.get(0).isEmpty()){ SingleCardWindow obj = new SingleCardWindow(decks.get(0).take()); while(obj.isVisible()){ } System.out.println("Closed"); } SingleCardWindow它是从JFrame继承的类。此代码显示牌组中的所有牌。显示一张卡,等待我关闭此窗口,然后显示下一张卡。在Windo

我有这个密码

while(!decks.get(0).isEmpty()){
   SingleCardWindow obj = new SingleCardWindow(decks.get(0).take());
   while(obj.isVisible()){

   }
   System.out.println("Closed");
}
SingleCardWindow它是从JFrame继承的类。此代码显示牌组中的所有牌。显示一张卡,等待我关闭此窗口,然后显示下一张卡。在Windows中,它工作得很好

在linux(java-oracle-7)中,“关闭”从不写入

但是如果我

while(!decks.get(0).isEmpty()){
   SingleCardWindow obj = new SingleCardWindow(decks.get(0).take());
   while(obj.isVisible()){
      System.out.println("SOMETHING");
   }
   System.out.println("Closed");
}

程序运行正常。所以,我认为编译器优化“while(obj.isVisible())”就像优化“while(true)”。我该怎么处理这个?我不需要任何代码进入循环。

在第二种情况下,您添加了这一行:

System.out.println("SOMETHING");
PrintStream#println
是一种同步方法,因此,如果这有助于您的程序开始工作,则很明显表明该方法
obj.isVisible
未同步,并且由于您不使用任何显式同步,因此实际上导致了程序中的数据竞争。读取线程从未观察到
isVisible
属性值的变化


但是,正如许多其他人已经注意到的,这只是回答了你提出的问题;您发布的代码还存在许多问题,其中使用了不适当的编程模型(忙等待)来解决基本上基于事件的问题。

在第二种情况下,您添加了这一行:

System.out.println("SOMETHING");
PrintStream#println
是一种同步方法,因此,如果这有助于您的程序开始工作,则很明显表明该方法
obj.isVisible
未同步,并且由于您不使用任何显式同步,因此实际上导致了程序中的数据竞争。读取线程从未观察到
isVisible
属性值的变化


但是,正如许多其他人已经注意到的,这只是回答了你提出的问题;您发布的代码还存在许多问题,其中包括用于解决基本上基于事件的问题的不适当的编程模型(忙等待)。

听起来像是
obj.isVisible()
正在从非
volatile
成员读取,没有显式同步。当然,一般来说,这样一个紧密的循环是一个非常糟糕的主意……请注意,即使你做到了这一点,你也永远不应该这样做。忙碌的等待效率极低。投票从来都不是一个好主意。有一些事件:使用侦听器并对其作出反应。为什么您认为这是一个编译器优化问题?听起来像是
obj.isVisible()
从非
volatile
成员中读取,而没有显式同步。当然,一般来说,像这样的紧密循环是一个非常糟糕的主意……请注意,即使您能够做到这一点,你永远不应该这样。忙碌的等待效率极低。投票从来都不是一个好主意。有一些事件:使用侦听器并对其作出反应。为什么您认为这是一个编译器优化问题?对不起,但我真的不明白为什么是“数据竞争”。我有两个线程,这是“主线程”和“JFrame线程”。JFrame线程可以更改JFrame对象中的“visible”属性。我关闭它-可见=错误。JFrame线程是关闭的,所以当主线程唤醒时,它读取visible False。我们总是有visible=true,并且不止一次-visible=false,我们不会在false和true之间交换值,所以主线程将正确读取value@chubakur如果一个值不是volitile/syncronized,则不能保证在一个线程上所做的更改在另一个线程上可见。他们都在查看自己的本地副本(之所以这样做是因为这样做效率更高,并且在需要线程间通信时可以使用volitile/syncronised,对不起,但我真的不明白为什么是“数据竞争”。我有两个线程,这是“主线程”,这是“JFrame线程”。JFrame线程可以更改为“可见”属性。我关闭它-visible=false。JFrame线程是关闭的,因此当主线程唤醒时,它将读取visible false。我们始终具有visible=true,并且不止一次-visible=false,我们不会在false和true之间交换值,因此主线程将正确读取value@chubakur如果某个值未自动/同步,则无法保证在一个线程上所做的更改在另一个线程上是可见的。他们都在查看自己的本地副本(这样做是因为效率更高,并且在需要线程间通信时可以使用volitile/syncronised)