จะหยุด / ฆ่า Java Thread ที่รันอยู่นานที่รันไทม์ได้อย่างไร หมดเวลา -> ยกเลิก -> สถานะถูกขัดจังหวะ
เผยแพร่แล้ว: 2021-07-17คุณเคยสงสัยหรือไม่ว่าจะฆ่าเธรด Java ที่รันเป็นเวลานานได้อย่างไร? คุณมีคำถามด้านล่างหรือไม่?
- ฆ่า/หยุดเธรดหลังจากช่วงเวลาหนึ่ง
- ฆ่าเธรดหลังจากเวลาที่กำหนดใน Java
- วิธีฆ่า Java Thread
- วิธีหยุดเธรดใน Java ด้วยตัวอย่าง
- วิธีหยุดเธรดในตัวอย่างโค้ดจาวา
- วิธีหยุดเธรดใน java โดยไม่ใช้วิธีหยุด
หากคุณมีคำถามใด ๆ ด้านล่างแสดงว่าคุณมาถูกที่แล้ว วันนี้เราจะมาดูตัวอย่างง่ายๆ ซึ่งสาธิตวิธี Java8 ในการฆ่าเธรดที่รันเป็นเวลานาน
ลอจิกคืออะไร:
- สร้างคลาส CrunchifyJavaTaskTimeout.java
- สร้าง Java Thread executor ที่มีขนาดเธรดพูลเพียง 1 ขนาด
- สร้าง 4 งานในอนาคตของวัตถุ
CrunchifyRunner
โดยหมดเวลา 3 วินาที - CrunchifyRunner.java เป็นคลาสง่าย ๆ ที่ใช้
call()
method- แนะนำการหน่วง
20 seconds
หากfutureTask = 4
- แนะนำการหน่วง
- เมื่อถึง
3 seconds
ในอนาคตจะสร้างข้อยกเว้นการหมดเวลาหากเธรดยังทำงานอยู่- เมื่อหมดเวลา เราต้องยกเลิกงานโดยใช้ crunchifyFuture
cancel( true )
; - เมื่อ FutureTask ถูกยกเลิก มันจะทริกเกอร์
InterruptedException
(โยนทิ้งเมื่อเธรดกำลังรอ อยู่ในสถานะสลีป หรือถูกใช้งาน และเธรดถูกขัดจังหวะ ก่อนหรือระหว่างกิจกรรม บางครั้งเมธอดอาจต้องการทดสอบว่าเธรดปัจจุบันถูกขัดจังหวะหรือไม่ และถ้าเป็นเช่นนั้น ให้โยนข้อยกเว้นนี้ทันที)
- เมื่อหมดเวลา เราต้องยกเลิกงานโดยใช้ crunchifyFuture
มาเริ่มกันเลย:
ขั้นตอนที่ 1 สร้างคลาส CrunchifyRunner.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 ) |
แจ้งให้เราทราบหากคุณมีคำถามใดๆ ในหัวข้อนี้