Taming implicit synchronizations in concurrent programs