[Java] Basic semaphore solution - 8ms, 36MB
"Semaphore is a bowl of marbles" - Professor Stark\n\n1. Semaphore is a bowl of marbles (or locks in this case). If you need a marble, and there are none, you w
"Semaphore is a bowl of marbles" - Professor Stark\n\n1. Semaphore is a bowl of marbles (or locks in this case). If you need a marble, and there are none, you wait. You wait until there is one marble and then you take it. If you release(), you will add one marble to the bowl (from thin air). If you release(100), you will add 100 marbles to the bowl. **run2.release();** will add one **"run2"** marble to the **"run2 bowl"**.\n2. The thread calling **third()** will wait until the end of **second()** when it releases a **\'run3\'** marble. The **second()** will wait until the end of **first() **when it releases a **\'run2\'** marble. Since **first()** never acquires anything, it will never wait. There is a forced wait ordering.\n3. With semaphores, you can start out with 1 marble or 0 marbles or 100 marbles. A thread can take marbles (up until it\'s empty) or put many marbles at a time.\n\nYou can solve this using other solutions (check bottom), but if you wake up a thread and make it spin in a loop and wait for some condition, it is a waste of CPU. You can make the thread go to sleep and wait for someone to notify it to wake up.\n\nUpvote and check out my other concurrency solutions.\n```\nimport java.util.concurrent.*;\nclass Foo {\n    Semaphore run2, run3;\n\n    public Foo() {\n        run2 = new Semaphore(0);\n        run3 = new Semaphore(0);\n    }\n\n    public void first(Runnable printFirst) throws InterruptedException {\n        printFirst.run();\n        run2.release();\n    }\n\n    public void second(Runnable printSecond) throws InterruptedException {\n        run2.acquire();\n        printSecond.run();\n        run3.release();\n    }\n\n    public void third(Runnable printThird) throws InterruptedException {\n        run3.acquire(); \n        printThird.run();\n    }\n}\n```\n\n---\n\nSide note:\n**ruzveld83** has pointed something out.\n"According to JMM there\'s no guarantee that a thread will see values assigned during construction of an object in another thread. There is no guarantee that some thread can\'t see version of Foo that is not fully constructed. It\'s possible to see Foo.run2 or Foo.run3 as nulls. And thread-safety of Semaphore class does not make any difference. The final keyword should fix this. See https://docs.oracle.com/javase/specs/jls/se8/html/jls-17.html#jls-17.5"\n\nI could argue that *maybe* Foo is being synchronized to allow for proper value visibility. But we can\'t see the entire program so... \xAF\\\\_(\u30C4)_/\xAF\n\n---\n\nHere\'s another solution that requires 1 semaphore. It is 19ms. There is some "waking and waiting" due to the loops, so that causes some CPU waste. I should also note that we need **tryAcquire(number)** because it will try to get "all or nothing." So if you **tryAcquire(3)**, it will try to "get all 3 if all present and return true" or "grab nothing and return false." If you use **acquire(3)**, if there isn\'t enough, it will grab 1 or 2 and then wait for the remainder. You may expect it to "get 3 or wait for 3" but it doesn\'t do this and you may be in for a surprise.\n```\nclass Foo {\n\n    Semaphore semaphore1;\n    public Foo() {\n        semaphore1 = new Semaphore(0);\n    }\n\n    public void first(Runnable printFirst) throws InterruptedException {\n        printFirst.run();\n        semaphore1.release();\n    }\n\n    public void second(Runnable printSecond) throws InterruptedException {\n        while(!semaphore1.tryAcquire(1));\n        \n        printSecond.run();\n        semaphore1.release(2);\n    }\n\n    public void third(Runnable printThird) throws InterruptedException {\n        while(!semaphore1.tryAcquire(2));\n        \n        printThird.run();\n    }\n}\n```\n---\nFor new learners, you can also solve this using:\n- **volatile** keyword.\n- locks\n- conditions (they are like sub-locks)\n- atomic variables\n- java\'s concurrent data structures\n\nUse what works and is simple.
[]