最近、私はプロジェクトで新しい要件に遭遇しました。これは、時限タスクを動的に追加できる関数を実装することです。これについて言えば、一部の人々はそれが単純であると言うかもしれません、クォーツを使用するだけで、それは単純で粗雑です。ただし、Quartzフレームワークは重すぎて、小さなプロジェクトを操作するのは簡単ではありません。もちろん、JDKはタイマーインターフェイスを提供していると言う人もいるかもしれませんが、これで十分です。ただし、プロジェクトの要件は完全にマルチスレッドモデルであり、タイマーはシングルスレッドであるため、著者は最終的にJDKのスレッドプールを選択しました。
スレッドプールとは何ですか
Javaは、エグゼキューターを通じて4種類のスレッドプールを提供します。
NewCachedThreadPool:キャッシュ可能なスレッドプールを作成します。スレッドプールの長さが処理のニーズを超える場合、アイドルスレッドを柔軟にリサイクルできます。リサイクルがない場合は、新しいスレッドを作成します。
NewFixedThreadPool:最大数のスレッドの同時性を制御できる固定長のスレッドプールを作成すると、余分なスレッドがキューで待機します。
NewsCheduledThreadPool:時限で定期的なタスクの実行をサポートする固定長スレッドプールを作成します。
NewsingLethReadExecutor:単一のスレッドスレッドプールを作成します。これは、一意のワーカースレッドのみを使用してタスクを実行し、すべてのタスクが指定された順序で実行されるようにします(FIFO、LIFO、優先度)。
ポスターは、プロジェクトでNewsCheduledThreadPoolを使用しています。それだけです。あなたがどれだけのポスターであっても、あなたはあなたのスキルを誇示します。グーグルとそれはたくさんあります。
スレッドプールサービスを取得します
著者は、Singletonモードを使用して、スレッドプールのサービスを取得します。コードは次のとおりです。
/***スレッドプール作成。 * @author wuhf * @date 2018/01/16 */public class threadpoolutils {private static stastic speduledexecutorservice executorservice; private threadpoolutils(){//手動でスレッドプールを作成します。 executorservice = new ScheduleDthreadPoolexecutor(10、new BasicThreadFactory.Builder()。namingpattern( "syncdata-schedule-pool-%d")。daemon(true).build()); } private static class pluginconfigholder {private final static threadpoolutils instance = new threadpoolutils(); } public static threadpoolutils getInstance(){pluginconfigholder.instanceを返します。 } public ScheduleDexecutorService getThreadPool(){return ExecutorService; }}実行中のスレッドコードの実装の中断
私はそれほどナンセンスとは言いません、コードは次のとおりです。
/***スレッドプールのタスクが中断されます。 */public class interruptthread runnable {private int num; public interruptthread(int num){this.num = num; } public static void main(string [] args)throws arturnedexception {thread interruptthread = newスレッド(new interruptthread(1)); scheduledfuture <? interrupthread interrupthread1 = new interruptthread(2); threadpoolutils.getInstance()。getthreadpool()。scheduleatfixedrate(interrupthread1,0,2、timeunit.seconds); interrupthread interrupthread2 = new interruptthread(3); threadpoolutils.getInstance()。getThreadPool()。scheduleatfixEdrate(interrupthread2,0,2、timeUnit.seconds); thread.sleep(5000); // running running stread interrupthread t.cancel(true); while(true){}} @override public void run(){system.out.println( "これはスレッド" + num); }}閉じ込められたレコード
ポスターが次のコードを使用していたとき、彼は突然、このタイミングタスクを停止する必要があるときにスレッドの実行を停止する方法について考えました。
threadpoolutils.getInstance()。getThreadPool()。scheduleatfixedrate(interrupthread、0,2、timeunit.seconds);
私はそのような必要があるので、それをグーグルしましょう。ほとんどの時間を検索した後、関連情報が見つかりませんでした。それらはすべて、Javaスレッドプールの詳細な分析でした。またはグローバル変数など、著者を満足させる解決策は見つかりませんでした。
スレッドがないので、ScheduleatFixEdrateの基礎となるソースコードを見て、それが何であるかを見てみましょう。予想どおり、ソースコードでScheduleatFixEdrateメソッドの特定の実装を見て、その返品値がスケジュールされていることを発見しました。
public ScheduledFuture <?> schedueAtFixEdrate(Runnable Command、Long InitialDelay、Long Period、TimeUnit Unit){if(command == null || unit == null)新しいnullpointerexception(); if(期間<= 0)新しいIllegalargumentException()を投げる; scheduledfuturetask <void> sft = new ScheduleDfutureTask <Void>(command、null、triggertime(initialdelay、unit)、unit.tonanos(inpering)); runnableScheduledfuture <void> t = decorateTask(command、sft); sft.outertask = t; delayedexecute(t); tを返します。 }次に、ScheduledFutureの中にあるものを見てみましょう。ポスターを失望させませんでした、そして私はこれを見ました
public boolean cancel(boolean may interrumpifrunning){boolean canceled = super.cancel(mayinterrumpifrunning); if(canceled && removeoncancel && heapindex> = 0)remove(this);キャンセルを返します;} //スレッドの実行中のキューから現在のスレッドを削除しますパブリックブーリアン削除(実行可能タスク){boolean removed = workqueue.remove(task); tryTerminate(); // shade shutdownとこれで空の返品が削除されました;}super.cancel(mayinterrumpifrunning)が何であるかを確認しましょう。私たちはこれを見ます。
//スレッドの割り込みメソッドを呼び出してスレッドの実行を停止しますパブリックブールンキャンセル(boolean may intrumptifrunning){if(state == new && unsafe.compareandswapint(this、state offset、new、may intruptifrunning?interrupting:canceled))return false; try {//ケースコールを介して、例外をスローする場合は(mayinterrumpifrunning){try {thread t = runner; if(t!= null)t.interrupt(); }最後に{// final state unsafe.putorderedint(this、stateOffset、挿入); }}}最後に{finishcompletion(); } trueを返します。 }ここでのすべての問題は解決されます。
要約しましょう
プロジェクトには常に難しい解決策があります。 Googleを見つけるのが簡単でない場合、JDKのソースコードを検索するのに適した方法かもしれません。