Using System.Schedule(), we can delay our execution to avoid concurrent batch execution in Salesforce.
Sample Code:
if ([SELECT count() FROM AsyncApexJob WHERE JobType='BatchApex' AND (Status = 'Processing' OR Status = 'Preparing')] < 1]){
Database.executeBatch(batchClassInstance);
} else {
Schedulable_Class sc = new Schedulable_Class();
Datetime dat = Datetime.now().addMinutes(30); // This is for 30 mins delay
String timeForScheduler = dat.format('s m H d M \'?\' yyyy');
Id scheduleId = System.Schedule('Trying again' + timeForScheduler, timeForScheduler,sc);
}