tja*_*ing 4 java multithreading
我有一个长期运行的Runnable.它在run()函数的while循环中执行大量迭代.我需要暂停和恢复runnable的功能,我使用pauseFlag可由另一个线程设置的volatile布尔值实现.
一旦可运行已检测到pauseFlagIS true,它要求pauseFlag.wait()暂停其执行.通过设置然后调用pauseFlag来完成恢复.falsepauseFlag.notifyAll()
所以这pauseFlag两者都充当了旗帜和互斥体.但是,这种组合功能不起作用.Runnable pauseFlag.wait()无限期地阻止.
如果我创建一个单独的互斥锁,比方说,Object mutex = new Object();并使用mutex.notifyAll()/ mutex.wait(),同时仍然使用pauseFlag布尔标志,Runnable 确实按预期行事.
非工作代码如下所示:
public class PausableRunnable implements Runnable
{
private boolean done;
private volatile Boolean pauseFlag = false;
/** Pause execution. This is an asynchronous (non-blocking) call. */
public void pause() // <-- called by another thread
{
pauseFlag = true;
}
/** Resume execution */
public void resume() // <-- called by another thread
{
pauseFlag = false;
synchronized (pauseFlag)
{
pauseFlag.notifyAll();
}
}
@Override
public void run()
{
try
{
while (!done && !Thread.currentThread().isInterrupted())
{
while (pauseFlag)
{
synchronized (pauseFlag)
{
// Pause flag was set. Suspend until we are notified that we can continue
pauseFlag.wait();
}
}
// execute our main behaviour. set done = true when done iterating.
// ....
}
} catch (InterruptedException e)
{
Thread.currentThread().interrupt();
}
}
}
Run Code Online (Sandbox Code Playgroud)
因此,虽然我通过使用单独的对象找到了解决方案,但我想了解这个问题.为什么上述实现不起作用?
我曾犯过同样的错误.
wait/ notify适用于对象,而不是引用
当您更改引用的对象时
private volatile Boolean pauseFlag
在wait仍参照原来的对象.(正如评论中指出的那样,通常只有两个布尔对象,TRUE并且FALSE这使得调试更难,因为你可能偶然得到正确的一个)
因此,最好使用final在使用wait/notify时永远不会更改其基础对象的引用.
| 归档时间: |
|
| 查看次数: |
282 次 |
| 最近记录: |