亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

Java 如何讓一個線程運行特定的時間,然后優雅的終止?

Java 如何讓一個線程運行特定的時間,然后優雅的終止?

www說 2018-10-11 17:24:09
有一個對象列表,按對象的過期時間戳升序排序,當內存快要不足時,想觸發一個線程從頭遍歷列表,把列表前面過期的對象都釋放掉(對象的資源是被pool的,必須手動release)列表不是線程安全的(因為程序其他部分邏輯的原因,這里使用線程安全的集合類并不能解決問題),工作線程和釋放資源的線程同時只能有一個操作對象列表我的想法是,如果釋放資源的線程在列表上操作太長時間,工作線程一直被阻塞,很長時間整個系統就不能提供服務了,所以我想限制每次釋放資源的線程的執行時間,在給定的時間里能釋放多少對象就釋放多少(并且時間結束時,是優雅的結束釋放工作),然后工作線程繼續執行請問如何實現我這個思路?如果同時只有一個線程訪問對象列表,是不是把釋放對象的工作放在工作線程中更好?怎么實現執行特定的時間呢?希望能有更標準的思路
查看完整描述

2 回答

?
UYOU

TA貢獻1878條經驗 獲得超4個贊

釋放是個輕量操作。如果你實在糾結阻塞時間我有個思路。
因為你的對象列表(假設叫ol)不是線程安全的,所以每次操作都會鎖住ol。
那可以單開一個守護線程輪詢jvm內存,一旦內存到達這個閥值就可以認為快用光了,然后將一個全局變了標記為true。
當你的工作線程發現這個全局變量為true后,在保存新對象到ol前,將ol最前面的幾個對象(1個或2個,不用多因為在輪詢線程沒發現內存回復前其他工作線程仍會釋放)釋放,然后保存新的。
那個輪詢內存的守護線程發現內存低于指定的閥值后在將全局變量設為false,這樣新的工作線程不會在有釋放操作。
這樣的話你完全沒有引入任何需要鎖ol的線程,你ol的阻塞率還是你原來的工作線程。由于輪詢內存線程是守護線程你也不用操心優雅的終止問題。

更新

突然發現你問的是如果讓線程運行指定的時間。。。。
線程卡在while前記一下開始時間,你循環里根據開始時間計算耗時,達到你指定的時候跳出或sleep都行。


查看完整回答
反對 回復 2018-10-14
?
BIG陽

TA貢獻1859條經驗 獲得超6個贊

工作線程和釋放資源的線程同時只能有一個操作對象列表

這個前提決定了你必須使用synchronized塊對操作這個列表的邏輯做保護,這個沒得說;
剩下的問題就是:如何讓回收線程操作列表的時間更短?

我的思路是這樣的:很簡單,你的回收線程在操作列表時,只做一件事情:把該回收的對象移出列表,放到另一個地方去(比如另一個列表,"列表2")

僅僅是“移出”的話,這個操作是非??斓模恢滥氵@個列表有多大,一般情況都能瞬間完成;

然后讓工作線程去操作列表,回收線程慢慢來處理"列表2"中的回收工作, 互不干擾;

如果你的對象列表確實很極端地大,那么你可以將回收線程設計成"主-次"線程2層結構,其中主線程開啟子線程對列表做移出操作,并持有子線程對象的應用;
而子線程,實現了interrupt方法,在方法中拋出一個你自定義的exception;

主線程在啟動子線程后,sleep(你認為合適的時間),醒來時若發現子線程還未結束,就調用子線程的interrupt方法


查看完整回答
反對 回復 2018-10-14
  • 2 回答
  • 0 關注
  • 4035 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號