2012-01-20 34 views
2

嗯,我不熟悉java中的線程,所以我正在處理這個問題:我有一個單例對象,它包含一些對象(讓說會話),每個對象都有一個持續時間,所以這意味着在一段時間之後,一個對象被認爲已過期,因此需要從單身(Singleton中的一個池 - 列表)中刪除。要做到這一點,我決定有一個線程每隔5分鐘(或10分鐘或其他)進行檢查,並清理單例類中的所有會話。我如何實現這樣的功能,以避免任何可能的死鎖和/或耗時的塊。先謝謝你。在Java中實現一個監視器線程

回答

2
Runnable cleaner = new Runnable() { 
public void run() { /* remove expired objects here */ 
    //Using get method check whether object is expired 
    } 
}; 
Executors.newScheduledThreadPool(1) 
     .scheduleWithFixedDelay(cleaner, 0, 30, TimeUnit.SECONDS); 
+0

這可能是我需要的。我不知道這個類(Executor及其所有派生類)感謝您的回覆。 – Elvis

3

我不會實現它這樣的。相反,當會話被請求到池時,我會刪除超時會話(儘管每次都不需要)。順便說一句,這是Guava's CacheBuilder所做的,你可以使用它,因爲它很簡單,經過測試並提供有用的功能。

如果您真的想這樣做,那麼您應該使用ConcurrentMap或ConcurrentList,並使用single-thread ScheduledExecutorService,它將喚醒遍歷列表並每隔X分鐘刪除較舊的會話。

+0

嗯,這是我一開始就想到的,但問題是:如果我們已經打開了100萬個會話,並且1000個會話斷開連接而沒有調用刪除會話方法。所以這會將會話保留在內存中。 – Elvis

+0

*從列表中獲取*會話時,緩存可以迭代會話並刪除過時的會話。從緩存中獲取會話應該非常頻繁,否則緩存將不會非常有用。 –

+0

使用弱引用創建會話對象,以便它們首先收集垃圾。 –

1

那麼你可以做這樣的事情:我假設你的單件對象的類被稱爲單,所以你有這樣的事情(它不是完美的代碼)

public class Singleton { 
    List<Objects> singletonList = Collections.synchronizedList(new ArrayList<Objects>); 



} 

public class RemoveExpiredItemsThread implements Runnable { 

    private Singleton singletonReference; 
    private int sleepTime = 5*60*1000; 
    // the constructor 

    // then the run method which is something like this 

    public void run() { 
     while(done == false) { 
     Thread.sleep(sleepTime); 
     singletonReference.removeItem(); 
     } 
    } 

} 
+0

其實這正是我所做的,但我不能肯定地說這是否是正確的解決方案。 – Elvis

2

我同意@quaylar(+ 1),如果可以的話,使用現有的緩存技術。

但是,如果你不能,一種解決方案是使用java.util.Timer。用第一個會話對象到期的時間初始化它,並將它放到睡眠狀態。然後,喚醒它,讓它刪除會話對象,並重置它到下一個到期時間。讓Java處理時序問題。

+0

嗯問題是,每次有會話被呼叫時,會話時間都會更新,如果此會話在一段時間內(e預定義時間)處於非活動狀態,它將保持不變。所以我不知道是否可以重新定時(重新設定它的時間)?這是否意味着我們應該爲每個會話設置一個計時器?如果有這麼多的內存消耗。 – Elvis

+0

@elvis嗨,整個緩存只需要一個計時器。此方法始終將計時器設置爲下一個到期對象到期時間所需的偏移量。因此,在每次喚醒時,您不要將計時器設置爲30秒,您總是將其設置爲任何時間,直到下一次到期爲止......現在,超出此範圍取決於您的底層緩存數據結構。如果它是有序的(TreeMap或List),那麼你知道下一個對象的順序是下一個到期。所以,不需要迭代列表來查找下一個將要到期的項目。 – wmorrison365

+0

你可以使用任何定時器機制,只要虛擬機正在看你的計時器(守護進程),這就是重要的方法,而不是實現。 – wmorrison365