簡體   English   中英

為什么我的線程在失敗時不超時?

[英]Why aren't my threads timing out when they fail?

所以不久前我問了一個問題: 在這里問了一個問題:“如果線程花費的時間太長,我該如何殺死線程”

我已經實現了那里提到的解決方案,但是在某些罕見的情況下,如果線程超時,程序仍然會失敗/鎖定(請參閱:保持main()方法打開,並防止程序進一步執行cron)。

這是我正在使用的來源:

 //Iterate through the array to submit them into individual running threads.
    ExecutorService threadPool = Executors.newFixedThreadPool(12);
    List<Future<?>> taskList = new ArrayList<Future<?>>();
    for (int i = 0; i < objectArray.length; i++) {
        Future<?> task = threadPool.submit(new ThreadHandler(objectArray[i], i));
        taskList.add(task);
        Thread.sleep(500);
    }

    //Event handler to kill any threads that are running for more than 30 seconds (most threads should only need .25 - 1 second to complete.
    for(Future future : taskList){
        try{
            future.get(30, TimeUnit.SECONDS);
        }catch(CancellationException cx){ System.err.println("Cancellation Exception: "); cx.printStackTrace();
        }catch(ExecutionException ex){ System.err.println("Execution Exception: ");ex.printStackTrace();
        }catch(InterruptedException ix){ System.err.println("Interrupted Exception: ");ix.printStackTrace();
        }catch(TimeoutException ex) {future.cancel(true);}
    }
    threadPool.shutdown();
    threadPool.awaitTermination(60, TimeUnit.SECONDS);

所以我的問題是:實施此代碼后,為什么執行程序服務不能在30秒后中斷工作。

因為我懷疑您的工作線程仍在運行。 您正在調用future.cancel(true); 但所做的只是在線程上設置中斷標志-它不會主動中斷正在運行的代碼。 “中斷”代碼的另一種方法是將一些volatile boolean shutdown標志設置為true,然后在代碼中進行測試。 有關中斷線程的更多詳細信息,請參見此處。

您需要確保ThreadHandler代碼正確處理中斷。 例如,它需要在循環或其他代碼塊中檢查Thread.currentThread().isInterrupted() 您還需要確保正確處理InterruptedException ,而不僅僅是吞咽中斷。

有關線程中斷的更多信息,請參見此處

您可能無法完成的每個任務都有越來越多的超時。 相反,您可以在超時后關閉線程池並取消其余線程。

threadPool.shutdown();
threadPool.awaitTermination(30, TimeUnit.SECONDS);
threadPool.shutdownNow(); // interrupt any running tasks.

《 Java並發實踐》一書中有一整章專門介紹了任務取消。 根據我的閱讀,任務取消必須在finally塊中,以確保任務總是結束。

    try{
            future.get(30, TimeUnit.SECONDS);

        } catch (TimeoutException e) {
           // log error message and falls through to finally block
        } catch (ExecutionException e) {
            throw e;
        } finally {
            future.cancel(true); // interrupt task
        }

處理InterruptedException時必須恢復中斷狀態。

           catch (InterruptedException e) {
                Thread.currentThread().interrupt();
            }

在ThreadHandler任務中,檢查Thread.currentThread()。isInterrupted()標志並在傳播中斷狀態為true時拋出InterruptedException。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM