Предупреждение : Эти программы представляют собой бомбы-клоны (разновидность менее опасной, но все же опасной формы вилочной бомбы); как таковые, не запускайте их в производственной системе без песочницы или ограничений ресурсов . Клонированные бомбы создают потоки в цикле (в отличие от вилочных бомб, которые создают процессы в цикле), таким образом, вы можете остановить их, просто убив рассматриваемый процесс (делая их намного менее опасными, чем вилочные бомбы, что может быть очень трудно проясняться); но они, скорее всего, будут связывать большую часть вашего процессора, пока вам не удастся это сделать (или пока программа не выйдет и не выйдет естественным путем сама). Если ваша операционная система ограничивает объем памяти и процессорного времени, которые эти программы могут использовать, должна создать безопасную среду для их тестирования.
Java (OpenJDK 8) , 65 60 байт (с небольшой модификацией оболочки)
Thread x=Thread.currentThread();new Thread(x::stop).start();
Попробуйте онлайн!
Требует, чтобы оба экземпляра catch (Exception …)в вопросе были изменены на catch (Throwable …). Теоретически это должно быть более безопасным, а не менее, но оно позволяет сделать это решение возможным.
Я сохранил 5 байтов поверх первой версии этого ответа, используя ссылку на метод, а не лямбду.
Java 4, 104 байта (не проверено, должно работать с оригинальной оболочкой)
final Thread x=Thread.currentThread();new Thread(){public void run(){x.stop(new Exception());}}.start();
Попробуйте онлайн! (ссылка идет на реализацию Java 8, поэтому не будет работать)
Используя функции, которые были удалены из современных версий Java, можно решить даже ту версию головоломки, которая требует Exception. Возможно, по крайней мере. (Java 4 сейчас очень старая, и я не могу вспомнить, какие функции она имела и не содержала. Как можно видеть, тогда в Java было намного меньше функций, и поэтому она была более многословной; у нас не было лямбды, поэтому мне пришлось создать внутренний класс.)
Пояснения
Большинство решений этого вопроса находятся на C # (вместе с решением Java, которое обманывает, используя несбалансированные скобки в качестве формы внедрения кода, и решением Perl, которое также отсутствует в Java). Поэтому я подумал, что стоит попытаться показать, как эта головоломка может быть решена «правильно» и в Java.
Обе программы фактически идентичны (поэтому тот факт, что первая программа работает, дает мне высокую уверенность в том, что вторая программа тоже будет работать, если только я случайно не использовал функцию, отличную от Java-4; Thread#stopв Java 5 она устарела).
Thread#stopМетод Java работает за кулисами, заставляя бросаемый объект бросаться в рассматриваемый поток. Функция throwable предназначена для этой цели ThreadDeath(в Errorчастности, потому что люди часто пытаются скрыть исключения, а разработчики Java не хотят, чтобы это происходило), хотя она позволяет вам что-либо генерировать (или раньше) в некоторый момент после того, как API был Разработчики Java поняли, что это невероятно плохая идея, и удалили версию метода, в которой аргументы принимаются прямо). Конечно, даже версия, которую выкидывает, ThreadDeathявляется довольно рискованной операцией, в отношении которой вы можете дать несколько гарантий (например, она позволяет решить эту головоломку, что-то, что «не должно быть» возможно), поэтому вы не должны используйте его, но на Java 8 он все еще работает.
Эта программа работает, порождая новый поток и заставляя его принудительно выбросить исключение обратно в основной поток. Если нам повезет, он сделает это в тот момент, когда мы находимся вне внутреннего catchблока (мы не можем выйти из внешнего catchблока, пока программа не завершится, потому что вокруг него есть цикл). Поскольку у нас уже удобно добавлен цикл, экономия байтов состоит в том, чтобы просто использовать этот цикл, чтобы позволить нам продолжать создавать потоки в надежде, что один из них в конечном итоге достигнет правильного времени. Обычно это происходит в течение нескольких секунд.
(Примечание TIO: текущая версия TIO довольно склонна убивать эту программу на ранних этапах ее выполнения, вероятно, из-за всех создаваемых потоков. Она может работать на TIO, но не работает надежно, поэтому часто требуется несколько попыток получите вывод «Вы выиграли!».)