java - while 循环的奇怪行为

标签 java multithreading compiler-optimization

所以我正在写一个视频播放库,细节并不重要。发生的事情是这段代码需要在解码器线程的 run() 方法结束时运行:

System.out.println("Video decoding complete");
int a = 0, b = 0;
do
{
    a = pictures.getCount();
    b = samples.getCount();
}while(a > 0 || b > 0);
Gdx.app.log("Status", videoPath + " completed playing successfully.");
videoComplete = true;

问题是,任何通过 do{}while 的东西都不会执行。这是奇怪的部分,这段代码在 while 循环中添加 System.out.println 时执行:

System.out.println("Video decoding complete");
int a = 0, b = 0;
do
{
    System.out.println("Waiting for packets to drain.");
    a = pictures.getCount();
    b = samples.getCount();
}while(a > 0 || b > 0);
Gdx.app.log("Status", videoPath + " completed playing successfully.");
videoComplete = true;

我怀疑编译器知道我正试图让它运行一个循环,但它暂时什么都不做,它只是剪掉代码或其他东西。但我真的不知道发生了什么。如果有人比我更了解,我希望有更好的解决方案。这么简单的事情我就卡在这里了!

最佳答案

我的猜测是 pictures.getCount() 和 samples.getCount() 读取非 volatile 字段。当您只读取一个非 volatile 字段时,出于性能原因,它可以被内联,但是如果您执行类似调用 synchronized 方法的操作(并且 System.out 是同步的),它不会优化代码方式,每次都必须执行查找。

我建议你尝试添加一个空的同步块(synchronized block),看看它是否仍然有效,即这样做而不是 println

synchronized(this) { }

关于java - while 循环的奇怪行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29736469/

相关文章:

java - Spring 测试 : better use XML configuration over annotations?

java - 从枚举构造列表<T>

java - 使用@Mock注解的对象是否应该设置详细值?

java - 使用字符串数组查找引号

java - 我如何安排gui和gui组件状态读取的线程同步?

java - 为什么这个类不是线程安全的?

python - 在不同模块中运行的线程之间共享队列

c# - 是否有用于 MSIL 结果的工具

加载字节时,Clang 不会将高位清零。这是一个错误还是一个故意的选择?

编译输出代码