Explanation of the solution in Java
You can use a countdownlatch, semaphore, regular mutex or lock object. I noticed a solution that relied upon volatile only but that is not right. A solution wit
You can use a countdownlatch, semaphore, regular mutex or lock object. I noticed a solution that relied upon volatile only but that is not right. A solution without wait/notify will cause CPU churns and spinning so you must introduce that if you are serious about MT safe programming. If you choose to go with CountDownLatch or Semaphores, you can create 2 indepent ones and there is an ordering one after another. I chose to use a lock object to demonstrate in detail how we enforce the ordering. Note that you must have a while loop to protect against the spurious wakeups. \n\n```\nimport java.util.concurrent.*;\n\nclass Foo {\n    private final Lock lock = new ReentrantLock();\n    private final Condition secondThread = lock.newCondition();\n    private final Condition thirdThread = lock.newCondition();\n    private int step = 1;\n    \n    public Foo() {\n        \n    }\n\n    public void first(Runnable printFirst) throws InterruptedException {\n        lock.lock();  \n        try {\n            // printFirst.run() outputs "first". Do not change or remove this line.\n            printFirst.run();\n            // signal 2nd.\n            step = 2;\n            secondThread.signal();\n        } finally {\n            lock.unlock();\n        }\n    }\n\n    public void second(Runnable printSecond) throws InterruptedException {\n        \n        // printSecond.run() outputs "second". Do not change or remove this line.\n        lock.lock();\n        try {\n            while (step != 2) {\n                // protect against spurious wakeups.\n                secondThread.await();        \n            }\n            printSecond.run();\n            thirdThread.signal();\n            step = 3;\n        } finally {\n            lock.unlock();\n        }\n    }\n\n    public void third(Runnable printThird) throws InterruptedException {\n        \n        // printThird.run() outputs "third". Do not change or remove this line.\n        lock.lock();\n        try {\n            while (step !=3) {\n                // protect against spurious wakeups.\n                thirdThread.await();\n            }\n            printThird.run();\n        } finally {\n            lock.unlock();\n        }\n    }\n}\n```
[]