2011-08-09 15 views
6

我必須在Java中編寫一個「WatchDog」,確保線程不會執行太長時間。隨着對象的初始化,它不成問題,我創建了一個類,它在run()方法中調用了WatchDog和構造函數。如何在java中保護方法(溢出等)

線程很容易停止,但我如何保證對象的正常方法? 例如,我調用一個對象的方法,這個方法執行一個無限循環,你會怎麼做?

感謝的對象

+0

也許方面會做? –

+0

「線程很容易停止」,不,它不是。我不明白「我如何確保正常的對象方法?」,無論是無限循環後面的例子。 – toto2

+0

http://download.oracle.com/javase/7/docs/technotes/guides/concurrency/threadPrimitiveDeprecation.html 閱讀全部內容,然後檢查是否仍想調用stop()。也許有些想在諺語框之外進行思考是解決問題的必要條件。 – RichColours

回答

3

普通方法上一些線程中運行。它可能是AWT事件調度程序或任何它調用的。或者它可能是控制檯應用程序的主線程。

它們與使用新線程()調用的線程沒有區別。

我想你的看門狗需要查看虛擬機中的所有線程,並尋找具有> =某個閾值利用率的線程。

到目前爲止你有什麼代碼?

豐富

+0

okey,也許我描述它是錯誤的,我給我的看門狗所有線程,我想觀察。 我只想初始化對象並運行線程中的每個方法,並將該線程交給我的看門狗。 – Nicolas

+0

嗨尼古拉斯 你能詳細說明嗎?具體來說,「我只想初始化對象並運行線程中的每個方法,並將該線程交給我的看門狗。」部分。我可能會幫忙,但我不明白你在做什麼。 – RichColours

+0

這裏是我的安全實例和安全方法調用代碼: http://pastebin.com/v8kdvdUW 希望你能理解我想要做的事情。 – Nicolas

4

首先,我要指出,停止線程容易。事實上,在一般情況下,線程不能安全地停止:

  • 您可以在您想要停止一個線程調用Thread.interrupt(),但不保證線程會發現中斷,更不用說實際停止。

  • 您可以調用已棄用的Thread.stop()方法,但此方法不安全。如果您在不幸的時刻調用它,則可以使數據結構保持半更新狀態,讓其他線程等待(永遠)不會到達的信號等等。


這裏是如何我實施方法執行看門狗。

首先,我會修改該方法以將兩個調用添加到看門狗服務;例如

public void someMethod(...) { 
    Watchdog.startMethod(maxTime); 
    // do stuff 
    Watchdog.endMethod(); 
} 

接下來,我會實現與下令到期時間優先級隊列看門狗:

  1. startMethod(maxTime)將增加與now + maxTime到期時間的條目添加到隊列中。該條目將包括當前線程(當方法被調用的參考。
  2. endMethod()將查找當前線程(中)進入隊列,如果發現將其刪除。
  3. 看門狗線程將定期查看第一個隊列條目,如果該條目的結束時間小於'now',則監視程序將刪除該條目,停止其線程並檢查下一個條目,重複直到下一個條目未到期。

需要考慮一些數據結構,以及處理endMethod調用被跳過的情況。 (實際上,由於一個方法調用可以向異常終止原因,該endMethod()呼叫確實需要在finally塊做。)

注意,startMethodendMethod調用可能(或許應該)通過註解插入處理器或類似的東西。


鑑於複雜性,而事實上,你不能保證停止線程(安全),我倒是覺得一些解決方案,不涉及法看門狗的。

+0

這是解決問題的正確方法。不知道爲什麼它沒有被選爲答案。如果有人想要現成的解決方案,請@yeorg256提供@Timeable。但它不能解決「中斷後清洗」的問題。就我個人而言,我仍然會寫我自己的方面。 –

1

嘗試使用@Timeable註釋從jcabi-aspects

public class Resource { 
    @Timeable(limit = 5, unit = TimeUnit.SECONDS) 
    public String load(URL url) { 
    return url.openConnection().getContent(); 
    } 
} 

你的方法在超時被打斷。