Well, from publicly available information (and I'm choosing to simply here for sake of not turning this answer into something the length of a book)...
- Apex code is run on a finite number of "Application Servers"
- Salesforce groups multiple customers together into a single "instance" or "pod"
- Since you have multiple customers, sometimes there are not enough resources (Application Servers) to serve everyone's requests at the same time
- Async requests (@future, schedulable, queueable, batch) are given less priority than synchronous requests
So "when resources are available" boils down to "your code will run when your pod is not super busy". Async execution gives Salesforce more flexibility to decide exactly when something is run. An important thing to note here is that your async code is not being run while it is in the "waiting" state.
The methods that Salesforce uses to schedule async work is generally not known outside of Salesforce itself. Suffice it to say that Salesforce has worked out how to do it, and it is "baked in" to the async feature that you're using. It's an implementation detail that Salesforce has worked out for us so we don't need to worry about it.
I've never heard of an async job completely being abandoned (if things got to that point, your pod would probably be inaccessible).