在我的计算机上,使用Java 8,即使地图访问已同步,以下程序也不会停止。那些同步的块难道不是吗?

import java.util.HashMap;
import java.util.concurrent.TimeUnit;

// Broken! - How long would you expect this program to run?
public class StopThread {
    private static HashMap<String, String> stopRequested = new HashMap<String, String>();

    public static void main(String[] args) throws InterruptedException {
        Thread backgroundThread = new Thread(new Runnable() {
            public void run() {
                int i = 0;
                synchronized (stopRequested) {
                    while (stopRequested.get("stop") == null)
                        i++;
                }
                System.out.println(i);
            }
        });
        backgroundThread.start();
        TimeUnit.SECONDS.sleep(1);
        synchronized (stopRequested) {
            stopRequested.put("stop", "true");
        }
    }
}

最佳答案

是的,这是预料之中的,您的backgroundThread在主线程之前持有该锁,并且直到主线程向地图写入“停止”时它才会释放该锁,主线程需要该锁将其写入“停止”,所以基本上这是一个死锁。

有几种方法可以解决此僵局,我想您要尝试的是查看在主线程在映射中写入“停止”条目之前计数的次数。
您只需在循环的每次迭代中获取并释放锁,这对您的情况就很有意义。

while (stopRequested.get("stop") == null)
    synchronized (stopRequested) {
                i++;
     }


另一个解决方案可能是使用currentHashMap,请检查此link以获取更多详细信息

07-24 19:24
查看更多