a spinlock and busy-waiting
Suppose a meeting room is occupied and you need it for ten seconds. You could go back to your desk and ask to be paged when it frees up (that costs a walk each way), or you could just stand at the door, checking the handle over and over until it opens. For a very short wait, standing and checking is faster. A spinlock is the 'stand at the door' strategy: a lock that, when it cannot be acquired, makes the thread loop tightly, re-testing the lock again and again until it becomes free, rather than going to sleep.
That tight re-testing loop is busy-waiting (or spinning): the CPU burns cycles doing nothing useful, just checking 'is it free yet?' The acquire is built on an atomic operation — typically an atomic exchange or compare-and-swap — so that the test-and-claim of the lock cannot itself be interrupted between two threads. A regular blocking mutex instead asks the operating system to put the waiting thread to sleep and wake it later, which is the right choice when the wait might be long. Spinning beats blocking when three things hold: the critical section is very short, the lock is rarely contended, and going to sleep and waking up (a context switch, costing thousands of cycles) would cost more than just spinning for the brief wait.
Spinlocks are everywhere inside operating-system kernels, where a context switch may be impossible or absurdly expensive — for instance while handling an interrupt. In ordinary application code they are usually the wrong default: if the lock holder gets preempted while you spin, you waste an entire time slice burning CPU for nothing, and on a single core a spinlock can be catastrophic (the holder can never run to release it while you hog the CPU spinning). The honest rule is: reach for a blocking mutex by default, and consider a spinlock only when you can show the critical section is tiny and contention is low.
A minimal spinlock: while (atomic_exchange(&lock, 1) == 1) { /* spin */ } to acquire, and atomic_store(&lock, 0) to release. The exchange atomically writes 1 and tells you the old value, so only the thread that saw a 0 has entered.
Busy-wait until the atomic exchange returns 0; spin only when the wait is tiny.
Spinning is not free even when uncontended: a naive spin loop hammers the cache line shared between cores, so real spinlocks add a 'pause' hint and often back off. A spinlock held across a sleep, a system call, or a long computation is almost always a bug.