警告:これらのプログラムはクローン爆弾(それほど危険ではないが、まだ危険な形式のフォーク爆弾)です。など、サンドボックスまたはリソース制限なしで本番システム上でそれらを実行しないでください。クローン爆弾は、ループ内にスレッドを作成します(ループ内にプロセスを作成するフォーク爆弾とは異なります)。したがって、問題のプロセスを強制終了するだけでスレッドを停止できます(フォーク爆弾よりも危険性が低くなります。片付ける); しかし、なんとかするまで(またはプログラムが勝って自然に終了するまで)、CPUのほとんどを占有する可能性があります。これらのプログラムが使用できるメモリ量とCPU時間を制限するようにOSに依頼すると、テストする安全な環境が作成されます。
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ソリューション、およびJavaにもないPerlソリューションと共に)。したがって、このパズルがJavaでも「適切に」解決される方法を示すのは試してみる価値があると思いました。
両方のプログラムは実質的に同一です(したがって、誤って非Java-4機能を使用した場合を除き、最初のプログラムが機能するという事実から、2番目のプログラムも機能するという確信が得られます。 Thread#stop
Java 5では非推奨になりました)。
JavaのThread#stop
メソッドは、問題のスレッドにthrowableをスローすることにより、舞台裏で機能します。目的のスロー可能オブジェクトはThreadDeath
(Error
特に、人々が例外を包括的にキャッチしようとし、Javaの設計者がそのようなことを望んでいないためです)、それはあなたが何かをスローすることを可能にします(または、APIの後のある時点でJavaの設計者は、これが信じられないほど悪いアイデアであることに気づき、引数を取るメソッドのバージョンを完全に削除しました)。もちろん、投げるバージョンでさえ、ThreadDeath
ほとんど保証することができないかなり危険な操作です(たとえば、このパズルを「不可能」に解決することができます)。それを使用しますが、Java 8の時点ではまだ動作します。
このプログラムは、新しいスレッドを生成し、メインスレッドに例外を強制的にスローするように要求することで機能します。運が良ければ、内側のcatch
ブロックの外側にいる時点でそれを行います(catch
ループが存在するため、プログラムが終了するまで外側のブロックをエスケープすることはできません)。ループは既に便利に追加されているため、そのループを使用してスレッドを作成し続けることで、そのうちの1つが最終的に正しいタイミングに到達することを期待して、バイトを節約できます。これは通常、数秒以内に発生するようです。
(TIO注:現在のバージョンのTIOは、おそらくすべてのスレッドが作成されているため、実行の早い段階でこのプログラムを強制終了する傾向があります。 「You won!」の出力を取得します。)