Your use of the term “Threads” is unusual and overlaps with other meanings for the term. In an OH context, there are a number of thread pools that OH pulls from to run just about everything. By default, the thread pool for Timers is of size 2 and Rules is of size 5. If you have more Rules than there are threads available in the pool trying to run at the same time, the later ones will have to wait until a thread frees up.
These have nothing to do with your VM “threads”.
See Why have my Rules stopped running? Why Thread::sleep is a bad idea for a full explanation.
But I tend to agree that your problem may not be related to this assuming you have no other long running or blocking commands like executeCommandLine or sendHttp*Request.