Обычно не убивают потоки извне, ибо это может привести к неопределённым последствиям.
Чтобы сделать что-то один раз из множества потоков, можно использовать, к примеру, атомарные булеаны.
Создаём инстанс
AtomicBoolean, ссылку на который имеют все эти потоки, который изначально будет
false.
Затем делаем CAS:
// AtomicBoolean isDeleted;
if (isDeleted.compareAndSet(false, true)) {
deleteMessage();
}
compareAndSet принимает ожидаемое значение и если оно действительно такое — изменяет флаг на то что мы хотим и возвращает true, если мы угадали, иначе false. И делается это атомарно. Т.е. только один поток изменит переменную и получит true и вызовет deleteMessage.
Но вообще, для этой задачи похоже вряд ли нужно действительно создавать потоки. Возможно вам нужна просто переменная, мол, «есть ли сейчас таймер, который вызовет deleteMessage», а так же
Timer, который вызовет deleteMessage через какое-то время. Его и отменить можно, если что.