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)