[Java] A few Easy-to-understand Solutions with Explanation
1. Using Semaphore\nA Semaphore manages a set of  virtual  permits; the  initial number of permits  is passed to the Semaphore constructor. Activities can acqui
## 1. Using Semaphore\nA `Semaphore` manages a set of  virtual  permits; the  initial number of permits  is passed to the Semaphore constructor. Activities can `acquire` permits (as long as some remain) and `release` permits when they are done with them. If no permit is available, acquire blocks until one is (or until interrupted or the operation times out). The `release` method returns a permit to the semaphore. (from the book [Java Concurrency in Practice](https://www.amazon.com/Java-Concurrency-Practice-Brian-Goetz/dp/0321349601))\n\nWe can use 2 Semaphores, one for each method. Each method will try to acquire its own semaphore permit before it proceed to the actual execution in each iteration. And after each method finishes a iteration, it will release a semaphore permit the other method is waiting for so that the other method can follow its execution.\n\nSolution is like below.\n```\nclass FooBar {\n    private int n;\n    private static Semaphore s1;\n    private static Semaphore s2;\n    public FooBar(int n) {\n        this.n = n;\n        s1 = new Semaphore(1); // give s1 a permit so that foo() can start first\n        s2 = new Semaphore(0);\n    }\n\n    public void foo(Runnable printFoo) throws InterruptedException {\n        for (int i = 0; i < n; i++) {\n            s1.acquire();\n        \t// printFoo.run() outputs "foo". Do not change or remove this line.\n        \tprintFoo.run();\n            s2.release();\n        }\n    }\n\n    public void bar(Runnable printBar) throws InterruptedException {\n        for (int i = 0; i < n; i++) {\n            s2.acquire();\n            // printBar.run() outputs "bar". Do not change or remove this line.\n        \tprintBar.run();\n            s1.release();\n        }\n    }\n}\n```\n\n## 2. Use Java\'s intrinsic lock (*synchronized*) and a *volatile* flag\nBecause we need alternative execution, we can use the intrinsic lock on the shared obect (`this` in this case) and release the lock to each other in each iteration using `wait()` and `notify()`.\n\nOnly being able to execute alternatively is not enough -- we also need to make sure` foo()` always starts first. Of course, we can use a flag value to control the execution condition and update the value in one thread to satisfy the execution condition of the other. This requries the value update to be visible to both threads. We can simply use the `volatile` keyword to achieve the visibility.\n\nThus, we have the below solution:\n```\nclass FooBar {\n    private int n;\n    private static volatile int flag;\n    public FooBar(int n) {\n        this.n = n;\n        this.flag = 1;\n    }\n\n    public synchronized void foo(Runnable printFoo) throws InterruptedException {\n        for (int i = 0; i < n; i++) {\n            while (flag != 1) {\n                wait(); // wait until the flag is 1\n            } \n        \t// printFoo.run() outputs "foo". Do not change or remove this line.\n        \tprintFoo.run();\n            flag++; // set condition for bar() execution\n            notify(); // notify wiating thread (which is bar() thread in this case)\n        }\n    }\n\n    public synchronized void bar(Runnable printBar) throws InterruptedException {\n        for (int i = 0; i < n; i++) {\n            while(flag != 2) {\n                wait(); // wait until the flag is 2\n            }\n            // printBar.run() outputs "bar". Do not change or remove this line.\n        \tprintBar.run();\n            flag--; // set condition for foo() execution\n            notify(); // notify wiating thread (which is foo() thread in this case)\n        }\n    }\n}\n```\n\nActually, we don\'t need to check the execution condition in every iteration, as we only need to make sure `foo()` starts first in the process (which is a one-time event). So, we can change the solution like below to avoid the unnecessary processing for the flag value:\n```\nclass FooBar {\n    private int n;\n    private static volatile int flag;\n    public FooBar(int n) {\n        this.n = n;\n        this.flag = 1;\n    }\n\n    public synchronized void foo(Runnable printFoo) throws InterruptedException {\n        flag++; // allow bar to execute\n        for (int i = 0; i < n; i++) {\n        \t// printFoo.run() outputs "foo". Do not change or remove this line.\n        \tprintFoo.run();\n            notify(); // notify bar() thread to proceed\n            wait();\n        }\n         notify(); // allow bar() to exit waiting state and finish\n    }\n\n    public synchronized void bar(Runnable printBar) throws InterruptedException {\n        // This is the condition that must be met when bar executes for the first time\n        // In case bar get hold on the intrinsic lock first when the whole process starts,\n        // it needs to relinquish the lock for foo to start first\n        if(flag != 2){\n            notify(); // allow foo() to start asap. makes a difference in the running time (maybe the driver program uses timed waiting to give initial execution some delay so notify() here helps to wake up the thread asap)\n            wait(); // relinquish lock for foo() to run first\n        }\n        for (int i = 0; i < n; i++) {\n            // printBar.run() outputs "bar". Do not change or remove this line.\n        \tprintBar.run();\n            notify(); // notify foo() thread to proceed\n            wait(); \n        }\n    }\n}\n```\n\n## 3. Other Utility Classes\nThere are of course other utility classes you can use to achieve the same effect (`CountDownLatch` `CyclicBarrier`, or even a `Lock` implementation of your own).\n\nJust another solution using `CountDownLatch` below:\n```\nclass FooBar {\n    private int n;\n    private static CountDownLatch barLatch;\n    public FooBar(int n) {\n        this.n = n;\n        this.barLatch = new CountDownLatch(2);\n    }\n\n    public synchronized void foo(Runnable printFoo) throws InterruptedException {\n        barLatch.countDown(); // count down once at the start\n        for (int i = 0; i < n; i++) {\n        \t// printFoo.run() outputs "foo". Do not change or remove this line.\n        \tprintFoo.run();\n            notify(); // notify bar() thread to proceed\n            wait();\n        }\n        notify(); // allow bar to exit the final iteration\n    }\n\n    public synchronized void bar(Runnable printBar) throws InterruptedException {\n\t\tbarLatch.countDown(); // count down once at the start\n        barLatch.await(); // wait the latch to count down to 0, i.e., both countDown() happens, which ensures foo() loop to be executed first\n        for (int i = 0; i < n; i++) {\n            // printBar.run() outputs "bar". Do not change or remove this line.\n        \tprintBar.run();\n            notify(); // notify foo() thread to proceed\n            wait(); \n        }\n    }\n}\n```
[]