0

我发现以下代码不起作用,因为 while 循环无限期地窃取了锁:

public void run()
{
    while(true)
    {
        synchronized(run)
        {
            if (!run) break;
            [code]
        }
    }
}

public void stopRunning()
{
    synchronized(run)
    {
        run = false;
    }
}

我的目标是确保在我知道我的 run() 函数不再实际运行之前,我不会从 stopRunning() 命令返回。我试图阻止 run 函数继续引用我正在销毁的其他东西。我的第一个想法是在 synchronized(run) 之前添加一行代码,例如 Thread.sleep(100) 以确保它释放锁。这是推荐的做法还是我忽略了某些东西[愚蠢/明显]?

谢谢!

4

5 回答 5

2

如果您只需要 stopRunning() 阻止直到 run() 完成操作,则可以使用设置为 1 的 CountDownLatch 。将其称为 stopSignal 或其他东西,在 run() 中,您可以在完成后调用 stopSignal.countDown() . 在 stopRunning 中,您可以设置 run() 完成的条件,然后调用stoppedSignal.await()。在 run() 通过倒计时“释放”闩锁之前,它不会继续。这只是一种更简洁的方法。所有被删除的同步块的东西。

当心“同步”关键字 - 这是一个非常生硬和旧的工具。并发包中有一些很棒的东西可以更巧妙地实现特定目的。“实践中的并发”是一本很棒的书。

于 2012-10-04T00:05:02.167 回答
0

这样的事情就足够了吗?

public void run()
{
    while(run)
    {
        [code]
    }

   onRunStopped();
}

public void stopRunning()
{
    run = false;
}

public void onRunStopped()
{
    // Cleanup
}
于 2012-10-04T00:04:56.873 回答
0

whilesynchronized(run)将锁定运行,您可以使用run.wait()冻结线程 run() 在另一个线程中执行。在另一个线程中,使用run.notify()run.notifyAll()获取 run() 以继续。

synchronized 用于在线程之间进行同步。仅当它们中的两个或更多之间存在潜在的竞争条件时才使用它。

于 2012-10-04T00:12:50.050 回答
0

确保代码中的两个点的“运行”对象相同。

while 循环应该与 stopRunning() 方法同步到同一个对象。

while 循环没有占用锁,这两条代码更有可能引用不同的对象。但我不能说,因为代码中没有显示运行对象。

于 2012-10-04T00:33:07.517 回答
0

可能有更优雅的解决方案,但我相信您可以通过以下更改来解决它:

private boolean lock;

public void run() 
{ 
    while(true) 
    { 
        synchronized(lock) 
        { 
            if (!run) break; 
            [code] 
        } 
    } 
} 

public void stopRunning() 
{ 
    run = false; 
    synchronized(lock){ } 
} 
于 2012-10-04T01:37:55.120 回答