Fast Java solution with good explanation.
This is a standart "producer-consumer" problem. Read this article:\nhttps://www.baeldung.com/java-wait-notify\n\nI hope this helps :)\n\n\nclass FooBar {\n    p
This is a standart "producer-consumer" problem. Read this article:\nhttps://www.baeldung.com/java-wait-notify\n\nI hope this helps :)\n\n```\nclass FooBar {\n    private int n;\n    private boolean printfoo = true; // set value to true so we can assure that foo() will be called first\n\n    public FooBar(int n) {\n        this.n = n;\n    }\n\n    public void foo(Runnable printFoo) throws InterruptedException {\n\n        for (int i = 0; i < n; i++) {\n\n            // printFoo.run() outputs "foo". Do not change or remove this line.\n            synchronized (this) {\n                /*\n                   If the first thread is here, that means it\'s already acquired\n                   this object\'s lock, so the second thread (or any other) gets blocked\n                   until the lock is released.\n                 */\n                while (!printfoo) {\n                    /*\n                        If wait() is called, the first thread releases the lock (VERY IMPORTANT)\n                        and waits until the other thread calls notifyAll() inside the bar() method.\n                        That guarantees our code won\'t deadlock.\n                     */\n                    wait();\n                }\n                printFoo.run(); // print "foo"\n                \n                /*\n                    Here we set printFoo to false in order to assure that if the thread scheduler\n                    chooses this thread again, it will stop on the while loop and wait for the second\n                    one.\n                 */\n                printfoo = false;\n\n                /*\n                    When notifyAll() is called, the second thread will get out of the while loop\n                    inside bar() and continue its job (to print "bar")\n                 */\n                notifyAll();\n            }\n        }\n    }\n\n    // the whole process is the same with the bar method\n    public void bar(Runnable printBar) throws InterruptedException {\n\n        for (int i = 0; i < n; i++) {\n\n            // printBar.run() outputs "bar". Do not change or remove this line.\n            synchronized (this) {\n                while (printfoo) {\n                    wait();\n                }\n                printBar.run(); // print "bar"\n                \n                printfoo = true;\n                notifyAll(); // wake up the first thread\n            }\n\t\t\t// lock is released\n        }\n    }\n}\n```
[]