Add: ok, so i can seperate the mutex and semaphore, and i just want to know is that my idea of counter right?
namely Release minus one and WaitOne add one, only if the counter bigger than zero, it will allow to run.
is this statement right?

I have some code that works well: run first() second() third() in order.

I just want to know how the counter in semaphore works? I know it is counter. Is that Release minus one and WaitOne add one, only if the counter bigger than zero, it will allow to run. Right?

However I read book about another thing, Mutex, the book says Mutex Waitone minus one, and release add one, so mutex is opposite to the semaphore? Right? 

Code:

```
using System;

namespace Algorithm.MultiThread
{
    class Semaphore
    {
        System.Threading.Semaphore s1, s2;
        public Semaphore()
        {
            s1 = new System.Threading.Semaphore(1, 5);
            s2 = new System.Threading.Semaphore(1, 5); //initialize as start counter 1
        }

        public void first()
        {
            Console.WriteLine("First");
            s1.Release(); // minus one
        }

        public void second()
        {
            s1.WaitOne(); //add one two times
            s1.WaitOne();
            Console.WriteLine("Second");
            s2.Release();
        }

        public void third()
        {
            s2.WaitOne(); // add one two times
            s2.WaitOne();
            Console.WriteLine("Third");

        }

        public void startnum(object obj)
        {
            int i = (int)obj;
            switch (i)
            {
                case 1:
                    first();
                    break;
                case 2:
                    second();
                    break;
                case 3:
                    third();
                    break;
                default:
                    break;
            }
        }

        public static void test()
        {
            Semaphore s = new Semaphore();
            System.Threading.Thread t1 = new System.Threading.Thread(new System.Threading.ParameterizedThreadStart(s.startnum));
            System.Threading.Thread t2 = new System.Threading.Thread(new System.Threading.ParameterizedThreadStart(s.startnum));
            System.Threading.Thread t3 = new System.Threading.Thread(new System.Threading.ParameterizedThreadStart(s.startnum));
            t1.Start(3);
            t2.Start(2);
            t3.Start(1);
        }
    }
}

```