In cooperative threading, a thread can only be suspended when it interacts with the runtime - so when it does I/O, or yields, or uses a lock, or maybe does some reflection, or perhaps allocates, or whatever. In preemptive threading, a thread can be suspended anywhere.
There is a bit of a grey area in between, where threads can be suspended outside the runtime, but not anywhere. Go had this for a while - threads could get suspended on function entry too.
If you've got a thread that's in a loop in which it doesn't allocate, doesn't call other functions, doesn't interact with the runtime in any way, maybe it's just looping over huge arrays of numbers doing calculations, then a cooperative threading runtime can't suspend it, whereas a preemptive threading runtime can.