(не для продвижения плохого дизайна), но чтобы ответить на ваши два вопроса:
... запретить запуск методов, если деструктор уже был вызван
Вы можете сделать это с помощью решения, предложенного @snemarch и @Simon (блокировка).Чтобы справиться с ситуацией, когда один поток находится внутри деструктора, в то время как другой ожидает блокировки в начале вашего метода, вам необходимо отслеживать состояние объекта потокобезопасным способом в памяти, разделяемой между потоками.Например, статический атомный int, который деструктор устанавливает в 0, прежде чем снимать блокировку.Метод проверяет int, как только он получает блокировку, и выдает под залог, если его 0.
... заставляет деструктор ждать, пока какой-либо метод выполнения не закончится
Решение, предложенное @snemarch и @Simon (блокировка), справится с этим.