Я не сделал бы этого так, проверяя общий объект.
Я, скорее всего, предоставит каждому потоку объект, чтобы отменить выполнение внутри собственного потока, будь то событие, переменная состояния потокобезопасности или что-то еще.
Проблема с контроллером совместного использования заключается в том, что с моей точки зрения логика отменяется, почему вы называете ее «контроллером», когда она ничего не контролирует?
Для меня контроллер операций должен получить заказ на отмену, а затем, в свою очередь, выбрать соответствующие потоки и сигнализировать им о прекращении. Это было бы правильной «цепочкой команд», если бы вы знали, что я имею в виду. То, как вы это делаете, вы вводите неестественное поведение в потоке, который не «подчиняется» ордерам останавливаться, а если проверяет каждый раз, если его «начальник» «написал порядок». Как-то это просто не так.
Кроме того, что, если вы просто один из «некоторых» потоков, чтобы остановиться в будущем? Что делать, если вы хотите включить некоторую расширенную логику, чтобы потоки перестали задавать условие? Затем вам придется переписать код в каждом потоке, чтобы обработать это условие.
Таким образом, я предоставил способ, чтобы каждый поток мог обрабатывать сигналы к ним, например, используя Command Pattern с структурой FIFO.
(Кстати, я понимаю, что они являются работниками пула потоков, а не фактическими классами Thread, но все же, я думаю, каждый рабочий должен сигнализироваться, чтобы останавливаться отдельно, а не наоборот).