You can easily get the details in apex
Integer enqueuedJobs = [SELECT COUNT() FROM AsyncApexJob WHERE JobType='BatchApex' AND Status IN ('Processing','Preparing','Queued')] ;
You can handle this in your code
//check if there are 5 active batch jobs
//In some cases, might need to add "Status='Queued' " to the criteria
if ([SELECT count() FROM AsyncApexJob WHERE JobType='BatchApex' AND (Status = 'Processing' OR Status = 'Preparing')] < 5){
Database.executeBatch(batchClassInstance);
} else {
//schedule this same schedulable class again in 30 mins
nameOfYourSchedulableClass sc = new nameOfYourSchedulableClass();
Datetime dt = Datetime.now().addMinutes(30); // i.e. 30 mins
String timeForScheduler = dt.format('s m H d M \'?\' yyyy');
Id schedId = System.Schedule('MatrixRetry'+timeForScheduler,timeForScheduler,sc);
}
Now with Apex Flex queue we can submit 100 batch for preocessing and they will be sitting in queue with status "Holding". Once we have available resource then it will start 5 processing them (5 parallel at a time) with status "Queued" and "Processing"
Reference