Different Approaches using JAVA
Using Semaphores :\n\njava\n\n class ZeroEvenOdd {\n        private int n;\n        private Semaphore zero, even, odd;\n\n        public ZeroEvenOdd(int n) {\n 
## Using Semaphores :\n\n```java\n\n class ZeroEvenOdd {\n        private int n;\n        private Semaphore zero, even, odd;\n\n        public ZeroEvenOdd(int n) {\n            this.n = n;\n            this.zero = new Semaphore(1);\n            this.even = new Semaphore(0);\n            this.odd = new Semaphore(0);\n        }\n\n        // printNumber.accept(x) outputs "x", where x is an integer.\n        public void zero(IntConsumer printNumber) throws InterruptedException {\n            for (int i = 1; i <= n; i++) {\n                zero.acquire();\n\n                printNumber.accept(0);\n                if (i % 2 == 0) {\n                    even.release();\n                } else {\n                    odd.release();\n                }\n\n            }\n        }\n\n        public void even(IntConsumer printNumber) throws InterruptedException {\n            for (int i = 2; i <= n; i += 2) {\n                even.acquire();\n                printNumber.accept(i);\n                zero.release();\n            }\n        }\n\n        public void odd(IntConsumer printNumber) throws InterruptedException {\n            for (int i = 1; i <= n; i += 2) {\n                odd.acquire();\n                printNumber.accept(i);\n                zero.release();\n            }\n        }\n\n    }\n```\n\n## Using Wait and NotifyAll Methods\n```java\n class ZeroEvenOdd {\n        private int n;\n        // private volatile int currState; no need to use volatile if using sync block\n        private int currState;\n        private final int ZERO, EVEN, ODD;\n\n        public ZeroEvenOdd(int n) {\n            this.n = n;\n            this.ZERO = 0;\n            this.EVEN = 2;\n            this.ODD = 1;\n            this.currState = ZERO;\n        }\n\n        // printNumber.accept(x) outputs "x", where x is an integer.\n        public void zero(IntConsumer printNumber) throws InterruptedException {\n            for (int i = 1; i <= n; i++) {\n                synchronized (this) {\n                    while (currState != ZERO)\n                        wait();\n\n                    printNumber.accept(0);\n                    if ((i & 1) == 1) {\n                        currState = ODD;\n                    } else {\n                        currState = EVEN;\n                    }\n\n                    notifyAll();\n                }\n            }\n        }\n\n        public void even(IntConsumer printNumber) throws InterruptedException {\n            for (int i = 2; i <= n; i += 2) {\n                synchronized (this) {\n                    while (currState != EVEN)\n                        wait();\n\n                    printNumber.accept(i);\n                    currState = ZERO;\n                    notifyAll();\n                }\n            }\n        }\n\n        public void odd(IntConsumer printNumber) throws InterruptedException {\n            for (int i = 1; i <= n; i += 2) {\n                synchronized (this) {\n                    while (currState != ODD)\n                        wait();\n\n                    printNumber.accept(i);\n                    currState = ZERO;\n                    notifyAll();\n                }\n            }\n        }\n    }\n\n\n```\n\n## Using Reentrant Locks and volatile variable\n\n```java\n\nclass ZeroEvenOdd {\n        private int n;\n        private Lock lock;\n        private Condition zero, odd, even;\n        private volatile int currState;\n        private final int ZERO, EVEN, ODD;\n\n        public ZeroEvenOdd(int n) {\n            this.n = n;\n            this.lock = new ReentrantLock();\n            this.zero = lock.newCondition();\n            this.odd = lock.newCondition();\n            this.even = lock.newCondition();\n            this.ZERO = 0;\n            this.EVEN = 2;\n            this.ODD = 1;\n            this.currState = ZERO;\n        }\n\n        // printNumber.accept(x) outputs "x", where x is an integer.\n        public void zero(IntConsumer printNumber) throws InterruptedException {\n            for (int i = 1; i <= n; i++) {\n                lock.lock();\n                try {\n                    if (currState != ZERO)\n                        zero.await();\n\n                    printNumber.accept(0);\n                    if (i % 2 == 0) {\n                        currState = EVEN;\n                        even.signal();\n                    } else {\n                        currState = ODD;\n                        odd.signal();\n                    }\n                } finally {\n                    lock.unlock();\n                }\n\n            } // for\n        }\n\n        public void even(IntConsumer printNumber) throws InterruptedException {\n            for (int i = 2; i <= n; i += 2) {\n                lock.lock();\n                try {\n                    if (currState != EVEN)\n                        even.await();\n\n                    printNumber.accept(i);\n                    currState = ZERO;\n                    zero.signal();\n                } finally {\n                    lock.unlock();\n                }\n            }\n        }\n\n        public void odd(IntConsumer printNumber) throws InterruptedException {\n            for (int i = 1; i <= n; i += 2) {\n                lock.lock();\n                try {\n                    if (currState != ODD)\n                        odd.await();\n\n                    printNumber.accept(i);\n                    currState = ZERO;\n                    zero.signal();\n                } finally {\n                    lock.unlock();\n                }\n            }\n        }\n    }\n\n\n```\n\n\nFrom last few days I am trying to solve these concurrency problems and have got to know about these three approaches, but I am still not sure which one is better and what to use in which scenario.\nAlso I got to now about the CountDownLatch Approach too where we have to be sure of certain number of tasks yet not completely sure where to use it\n\n\n**, If you all know some good resources please let me know in the comments**
[]