为什么线程中的 Java 循环不起作用?
我正在用java编写一个收音机,并且正在使用一个线程来播放流。我在线程的run方法中有一个while循环,它检查一个名为shouldPlay的变量是否为true,如果是,则运行玩家。然后,我有一个暂停()方法,它将变量设置为 false,自然我希望它在变量为 false 时不运行播放器。我创建了一个小例子来说明如何在下面进行设置:
class audiostream extends Thread {
private boolean shouldPlay = true;
@Override
public void run() {
while(true)
{
if(shouldPlay)
{
shouldPlay = false;
System.out.print("test");
}
}
}
public void pause() {
shouldPlay = false;
}
public void play() {
shouldPlay = true;
}
}
我想要发生的是当线程首次运行时,它应该打印“test”(它做得很好)。然后,当您运行pause()时,它应该将shouldPlay设置为false并且不允许打印出“test”。但是当你调用 play() 时,它应该将 shouldPlay 设置为 true,然后再次打印出测试。问题是它没有这样做。
但大约有 1/100 的时间会发生。我是否正确地假设这里的问题是即使我从另一个线程调用 play() 和pause() 以免“挂起”父线程,但我的子线程挂在该 while 循环上并且在调用 play() 或从父级暂停()变量不会因为该循环而改变值?如果是这样我就不知道该怎么办了!
I'm coding a radio in java and am using a thread to of course play the stream in. I have a while loop in the run method of the thread which checks if a variable called shouldPlay is true, and if it is it runs the player. Then, I have a pause() method which sets the variable to false and naturally I want it to not run the player when the variable is false. I've created a small example of how I've set it up below:
class audiostream extends Thread {
private boolean shouldPlay = true;
@Override
public void run() {
while(true)
{
if(shouldPlay)
{
shouldPlay = false;
System.out.print("test");
}
}
}
public void pause() {
shouldPlay = false;
}
public void play() {
shouldPlay = true;
}
}
What I want to happen is when the thread first runs, it should print "test" (which it does fine). Then when you run pause() it should set shouldPlay to false and not allow "test" to be printed out. But then when you call play() it should set shouldPlay to true then print out test again. The problem is it's not doing this.
About 1/100th of the time it will though. Am I right to assume the problem here is even though I call play() and pause() from another thread as not to "hang" the parent thread, that my child thread is hanging on that while loop and when calling play() or pause() from the parent the variables don't change value because of that loop? If that's the case I don't know what I should do!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
添加“易失性”将修复它
add 'volatile' will fix it
shouldPlay
应该是易失性
,请删除 -shouldPlay = false;
,shouldPlay
should bevolatile
and please remove -shouldPlay = false;
,您可以使用 AtomicBoolean 作为替代方案。
You can make use of AtomicBoolean as an alternative.
Java 内存模型仅保证线程在与其他线程同步时能够看到其他线程所做的更改。 Java 语言规范 定义 < em>同步如下:
在您的示例中,写入 shouldPlay 的线程和读取它的线程没有执行任何操作,因此无法建立同步。因此,未指定读取线程是否以及何时会注意到新值。
在您的情况下,声明
shouldPlay
volatile
是建立同步的最简单方法。The Java Memory Model only guarantees that threads will see changes made by other threads if they synchronize-with those threads. The Java Language Specification defines synchronized-with as follows:
In your example, the thread writing shouldPlay and the thread reading it do none of that, thereby failing to establish
synchronized-with
. Therefore it is unspecified if and when the reading thread will notice the new value.In your case, declaring
shouldPlay
volatile
is the easiest way to establish that synchronization.