A CPU, in this context, is a single physical chip which can be installed separately from other CPUs on the computer (should there be a place for multiple CPUs).
A "core" is a processing element of a CPU that is a distinct piece of hardware from other cores. If a CPU provides more than one core, the expectation is that the cores not only execute independently of each other, but that they do not contend for most resources on the same CPU to do their execution. That is, multiple cores provided by the same CPU are not sharing much of the CPU's hardware.
A "thread" in this context(note: the term "thread" as used in most programming contexts is related but different) is a path of code execution, with its own distinct set of registers. A core provides one or more threads. However, if a CPU core exposes multiple threads (typically only 2), the expectation is that the threads do contend with each other for execution resources.
The idea with multi-threaded cores (commonly called hyperthreading) is that cores have lots of execution resources. And a single stream of instructions cannot always saturate all of these resources. So if a core runs instructions from two threads, it can more efficiently use its computational resources.
And sometimes operations just shut a thread down. Memory fetches often can stop a thread in its tracks to wait for the data from RAM. At those times, a second thread on the core will get the core to itself until the data arrives.