実行時に長時間実行されているJavaスレッドを停止/強制終了するにはどうすればよいですか? タイムアウト->キャンセル->中断状態
公開: 2021-07-17長時間実行されているJavaスレッドを強制終了する方法を考えたことはありますか? 以下の質問はありますか?
- 一定期間後にスレッドを強制終了/停止します
- Javaで指定された制限時間後にスレッドを強制終了する
- Javaスレッドを強制終了する方法
- 例を使用してJavaでスレッドを停止する方法
- Javaコード例でスレッドを停止する方法
- stopメソッドを使用せずにJavaでスレッドを停止する方法
以下の質問のいずれかがある場合は、適切な場所にいます。 今日は、長時間実行されているスレッドを強制終了するJava8の方法を示す簡単な例について説明します。
ロジックとは:
- クラスCrunchifyJavaTaskTimeout.javaを作成します
- スレッドプールサイズが1つだけのJavaスレッドエグゼキュータを作成します。
- 3秒のタイムアウトで
CrunchifyRunner
オブジェクトの4つの将来のタスクを作成します - CrunchifyRunner.javaは、
call()
メソッドを実装する単純なクラスです。-
futureTask = 4
場合、20 seconds
の遅延が発生します
-
- 将来が
3 seconds
に達すると、スレッドがまだ実行されている場合はタイムアウト例外が発生します- タイムアウトになったら、crunchifyFutureを使用してタスクをキャンセルする必要があります。
cancel( true )
; - futureTaskがキャンセルされると、
InterruptedException
がトリガーされます(スレッドが待機中、スリープ中、またはその他の方法で占有されている場合にスローされ、アクティビティの前または最中にスレッドが中断されます。メソッドは、現在のスレッドが中断されたかどうかをテストしたい場合があります。その場合は、すぐにこの例外をスローします。)
- タイムアウトになったら、crunchifyFutureを使用してタスクをキャンセルする必要があります。
始めましょう:
ステップ-1CrunchifyRunner.javaクラスを作成します
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 |
package crunchify . java . tutorials ; import java . text . SimpleDateFormat ; import java . util . Date ; import java . util . concurrent . Callable ; /** * @author Crunchify.com * Version: 1.0.1 * */ public class CrunchifyRunner implements Callable < Boolean > { private int workerNumber ; public int getNumber ( ) { return workerNumber ; } public void setNumber ( int workerNumber ) { this . workerNumber = workerNumber ; } public CrunchifyRunner ( int workerNumber ) { this . workerNumber = workerNumber ; setNumber ( workerNumber ) ; } SimpleDateFormat crunchifyFormatter = new SimpleDateFormat ( "dd-MMMMM-yyyy hh:mm:ss" ) ; public Boolean call ( ) throws InterruptedException { try { if ( workerNumber == 4 ) { // Sleep for 20 Seconds to generate long running thread. Thread . sleep ( 20000 ) ; } else { Thread . sleep ( 50 ) ; } } catch ( InterruptedException ie ) { log ( "\n" + crunchifyFormatter . format ( new Date ( ) ) + " crunchifyWorker task " + workerNumber + " interrupted." ) ; log ( "\n=======> Basically once thread is timed out, it should be cancelled and interrupted. (timedout ==> cancelled ==> interrupted)" ) ; } // Thrown when a thread is waiting, sleeping, or otherwise occupied, and the thread is interrupted, either before or during the activity. Occasionally a // method may wish to test whether the current thread has been interrupted, and if so, to immediately throw this exception. return true ; } public void log ( String info ) { System . out . println ( info ) ; } } |
ステップ-2クラスCrunchifyJavaTaskTimeout.javaを作成します
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 |
package crunchify . java . tutorials ; import java . text . SimpleDateFormat ; import java . util . ArrayList ; import java . util . Collection ; import java . util . Date ; import java . util . List ; import java . util . concurrent . Callable ; import java . util . concurrent . CompletionService ; import java . util . concurrent . ExecutionException ; import java . util . concurrent . ExecutorCompletionService ; import java . util . concurrent . Executors ; import java . util . concurrent . Future ; import java . util . concurrent . TimeUnit ; /** * @author Crunchify.com * Version: 1.0.2 * */ public class CrunchifyJavaTaskTimeout { @ SuppressWarnings ( { "rawtypes" , "unchecked" } ) public static void main ( final String [ ] args ) { // Creates an ExecutorCompletionService using the supplied executor for base task execution and a LinkedBlockingQueue as a completion queue. CompletionService < Boolean > crunchifyService = new ExecutorCompletionService < Boolean > ( Executors . newFixedThreadPool ( 1 ) ) ; Collection < CrunchifyRunner > crunchifyThreads = new ArrayList < CrunchifyRunner > ( 50 ) ; crunchifyThreads . add ( new CrunchifyRunner ( 1 ) ) ; crunchifyThreads . add ( new CrunchifyRunner ( 2 ) ) ; crunchifyThreads . add ( new CrunchifyRunner ( 3 ) ) ; crunchifyThreads . add ( new CrunchifyRunner ( 4 ) ) ; SimpleDateFormat crunchifyFormatter = new SimpleDateFormat ( "dd-MMMMM-yyyy hh:mm:ss" ) ; List < Future < Boolean > > crunchifyFutures = new ArrayList < Future < Boolean > > ( crunchifyThreads . size ( ) ) ; try { // Let's first add all tasks to future for ( Callable crunchifyTask : crunchifyThreads ) { crunchifyFutures . add ( crunchifyService . submit ( crunchifyTask ) ) ; } for ( int count = 1 ; count < = crunchifyFutures . size ( ) ; count ++ ) { // Let's put Future timeout to 3 Seconds Future < Boolean > crunchifyResult = crunchifyService . poll ( 3000 , TimeUnit . MILLISECONDS ) ; if ( crunchifyResult == null ) { log ( crunchifyFormatter . format ( new Date ( ) ) + "\n ==> crunchifyWorker task " + count + " timedout." ) ; // So lets cancel the first futures we find that haven't completed for ( Future crunchifyFuture : crunchifyFutures ) { if ( crunchifyFuture . isDone ( ) ) { continue ; } else { crunchifyFuture . cancel ( true ) ; log ( " ==> crunchifyWorker task " + count + " cancelled." ) ; break ; } } continue ; } else { try { if ( crunchifyResult . isDone ( ) && !crunchifyResult.isCancelled() && crunchifyResult.get()) { log(crunchifyFormatter.format(new Date()) + " ==> crunchifyWorker task " + count + " completed."); } else { log ( crunchifyFormatter . format ( new Date ( ) ) + " ==> crunchifyWorker task failed" ) ; } } catch ( ExecutionException exception ) { log ( exception . getMessage ( ) ) ; } } } } catch ( InterruptedException exception ) { // Log exception message log ( exception . getMessage ( ) ) ; } finally { // Cancel by interrupting any existing tasks currently running in Executor Service for ( Future < Boolean > future : crunchifyFutures ) { future . cancel ( true ) ; } } log ( "\n=======> All tasks completed. Now long running thread 4 should be interrupted immediately after this." ) ; System . exit ( 0 ) ; } private static void log ( String string ) { System . out . println ( string ) ; } } |

ステップ-3
CrunchifyJavaTaskTimeout.javaを右クリックして、Javaアプリケーションとして実行します。
以下の結果がEclipseコンソールに表示されます。
1 2 3 4 5 6 7 8 9 10 11 12 |
27 - November - 2018 10 : 32 : 29 == > crunchifyWorker task 1 completed . 27 - November - 2018 10 : 32 : 29 == > crunchifyWorker task 2 completed . 27 - November - 2018 10 : 32 : 29 == > crunchifyWorker task 3 completed . 27 - November - 2018 10 : 32 : 32 == > crunchifyWorker task 4 timedout . == > crunchifyWorker task 4 cancelled . ======= > All tasks completed . Now long running thread 4 should be interrupted immediately after this . 27 - November - 2018 10 : 32 : 32 crunchifyWorker task 4 interrupted . ======= > Basically once thread is timed out , it should be cancelled and interrupted . ( timedout == > cancelled == > interrupted ) |
このトピックについて質問がある場合はお知らせください。