Android 在While循环中使用Synchronized

Android 在While循环中使用Synchronized,android,thread-safety,synchronized,Android,Thread Safety,Synchronized,我发现以下代码不起作用,因为while循环无限期地窃取锁: public void run() { while(true) { synchronized(run) { if (!run) break; [code] } } } public void stopRunning() { synchronized(run) { run = false

我发现以下代码不起作用,因为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),以确保它释放锁。这是推荐的做法还是我忽略了一些[愚蠢/明显的]


谢谢

像这样的东西够了吗

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

   onRunStopped();
}

public void stopRunning()
{
    run = false;
}

public void onRunStopped()
{
    // Cleanup
}

如果您只需要stopRunning()阻塞直到run()完成操作,您可以使用设置为1的CountDownLatch。调用它stoppedSignal或其他什么,在run()中,您可以在完成时调用stoppedSignal.countDown()。在stopRunning中,您可以设置run()完成的条件,然后调用stoppedSignal.await()。直到run()通过倒计时“释放”闩锁,它才会继续。这只是一种更整洁的方法。所有需要清除的同步块内容

当心“synchronized”关键字——这是一个非常生硬和陈旧的工具。并发包中有一些奇妙的东西,它们可以更灵活地实现特定的目的。《实践中的并发性》是一本非常棒的书。

同步(运行)
将锁定运行时,您可以使用
运行。等待()
来冻结在中执行的线程run()。 在另一个线程中,使用
run.notify()
run.notifyAll()
获取run()继续


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

确保“run”对象在代码中的两个点上都相同

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


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

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

private boolean lock;

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

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

我看不出有什么消息给我。您是否有一些您认为我可能会看到的特定内容?也许我在这一点上不正确,但因为您在只读情况下使用run变量,所以不必担心使用synchronize。如果您将条件变量标记为volatile,这是正确的,您将不需要同步。但是run()可能需要一段时间才能意识到条件变量的值已更改,并且它将继续访问被另一个线程破坏的内容。调用stopRunning()的线程需要等待run()线程完成。二进制信号量也可以工作,因为我们不知道run()将要做多少工作。条件变量需要标记为“volatile”,这样才能保证对它的写入对执行run()的线程可见。我想我一直坚持使用synchronized,因为使用更常见的“信号量”方法肯定有好处。倒计时闩锁似乎起到了作用。谢谢我喜欢notify()和wait()的想法,因为我认为一般的“信号量”概念最适合我的应用程序。我并没有意识到我可以像对待synchronized一样将对象当作信号量。但显然有一个问题:我的wait()不能保证在所有情况下都在notify()之前被调用,这会导致致命错误。我需要一个真正的信号灯吗?