Java 謎題 2:夢境

jdon發表於2019-09-16


你有沒有從夢中醒來,然後發現你真的還在做夢?如果你醒來,你怎麼知道你回到了現實?這個難題實現了該問題的解決方案:當您進入和退出夢想時,您可以計算夢境的遞迴級別:

package sleep;
 
import dream.Dream;
 
public class Sleeper {
    private int level;
     
    public synchronized int enter(Dream dream) {
        level++;
        try {
            dream.dream(this);
        } finally {
            level--;
        }
        return level;
    }
}


睡眠者開始睡覺並進入夢境(第一級)。他可以在夢裡做一個夢,甚至進入更深層次的夢。但當他離開表層的夢時,他再次醒來,所以他應該再次回到零級,對吧?

package sleep;
 
import dream.Dream;
 
public class Main {
    public static void main(String[] args) {
        if (new Sleeper().enter(new Dream()) != 0) {
            // The goal is to reach this line
            System.out.println("Am I still dreaming?");
        }
    }
}


 levels 計數看起來非常安全,所以這似乎是不可能的:
  • 每次進入夢境level都會增加。由於finally阻擋,沒有辦法離開夢境而不再減少它。
  • synchronized塊確保沒有其他執行緒可以同時呼叫它。從夢的方法返回級別,以確保它在synchronized塊內讀取。
  • 進入夢境時lever必須是零,那麼從它返回的值也必須為零,因為即使我們遞迴地呼叫它,我們也必須輸入與退出同樣多的夢境。

// this is the only file you're allowed to edit
package dream;
 
import sleep.Sleeper;
 
public class Dream {
    public void dream(Sleeper s) {
        // TODO implement me
    }
}


你能找到這個推理中的缺陷嗎?你能想象一個真正奇怪的夢想會讓睡眠者失去理智嗎?