Clean and easy java solution
\nimport java.util.concurrent.Semaphore;\n\nclass Foo {\n\n    final Semaphore hasFirstRun = new Semaphore(0);\n    final Semaphore hasSecondRun = new Semaphore
```\nimport java.util.concurrent.Semaphore;\n\nclass Foo {\n\n    final Semaphore hasFirstRun = new Semaphore(0);\n    final Semaphore hasSecondRun = new Semaphore(0);\n\n    public void first(Runnable printFirst) throws InterruptedException {\n        printFirst.run();\n        hasFirstRun.release(); // Allows second() to run, and wakes it if it\'s sleeping.\n    }\n\n    public void second(Runnable printSecond) throws InterruptedException {\n        /*\n            hasFirstRun is initialized to 0. This means that if second() is executed\n            before first(), it can\'t get the lock and goes to sleep. In this case, it\n            will be waked up by first().\n            \n            If second() is executed after first(), then it can acquire the semaphore immediately\n            and execute its code.\n        */\n        hasFirstRun.acquire(); \n        printSecond.run();\n        hasSecondRun.release();\n    }\n\n    public void third(Runnable printThird) throws InterruptedException {\n        hasSecondRun.acquire(); // same logic as second()\n        printThird.run();\n    }\n}\n```
['Java']