전에 만들었던 SpinLock은 계속 무한으로 돌면서 확인해서 키를 얻는 것이이다. 여기서 키를 누가 사용하고 있어 얻는 것을 실패했다면 자신이 보장받은 시간을 다른 스레드에게 양보해주는데 이때 3가지 방법이 있다.
Thread.Sleep(1)
무조건 1ms를 쉬겠다는 의미이다. (인자는 1이 꼭 아니여도 된다.) 단 저렇게 쓴다고 해서 꼭 1ms를 쉬는 것은 아니다. 몇 초를 쉬다가 실행할건지는 운영체제가 결정한다. 하지만 우리가 요청한 시간과 최대한 비슷한 시간을 정해준다.
Thread.Sleep(0)
이것은 자신보다 우선순위가 높거나 같은 스레드에게 양보한다. 자신보다 낮은 스레드에게는 양보하지 않는데 이러면 우선순위가 낮은 스레드는 기아현상응 겪을 수 있다.
Thread.Yield()
현재 실행 가능한 스레드가 있으면 우선순위 상관없이 양보한다. 실행 가능한 것이 없으면 남은 시간을 본인이 사용한다.
이렇게 3가지 방법으로 보장받은 시간을 다른 스레드에게 양보할 수 있는데 이것을 Context Switching이라고 한다. 쓰지 않을 시간을 다른 스레드에게 양보하는 거니까 좋아보이는데 사실 그렇지 않다.
Context Switching은 사실 비용이 많이 들어간다.
Thread_1을 실행하고 있다가 Thread_3을 실행한다고 하면 아래 그림처럼 된다.

Thread_3을 실행하기 위해서는 OS커널을 한 번 거쳤다가 가야한다. 또한 레지스터를 변경해야하는데 실행하는 스레드를 변경하기 위해서는 레지스터도 복원해야한다. 실행중이던 Thread_1의 온갖 상태를 메모리에 저장하고 Thread_3의 온갖 정보를 레지스터에 올리는 작업이 필요하다.
정리하면 자신의 시간을 포기하고 양보하는 것이 꼭 좋은 것이 아니다. 굳이 양보를 하지 않고 남은 시간동안 SpinLock처럼 계속 기다리는 것이 상황에 따라 좋을 수도 있다.