CPU usage is calculated by the OS, eg for a given core it is the proportion of time over some period (eg the last second) that the OS was able to schedule a thread on that core. Waiting on RAM (or some other things like execution resources, especially with SMT) is handled by the CPU itself, so a thread that is "stalled" because of this is still "running" from the OS point of view, and the time still counts as CPU usage.
On the other hand, a thread that is "stalled" waiting for data from storage (including paging activity) is different: in this case, the OS gets involved and will suspend the thread, marking it unable to be scheduled again until after the data are available. Suspended threads do not contribute to CPU usage.