6
A
回答
3
通常,我只是從線程代碼中定期輪詢一個控制對象。喜歡的東西:
interface ThreadControl {
boolean shouldContinue();
}
class Timer implements ThreadControl {
public boolean shouldContinue() {
// returns false if max_time has elapsed
}
}
class MyTask implements Runnable {
private tc;
public MyTask(ThreadControl tc) {
this.tc = tc;
}
public void run() {
while (true) {
// do stuff
if (!tc.shouldContinue())
break;
}
}
}
5
如何:
提交您Callable
爲ExecutorService
和保持一個句柄返回Future
。
ExecutorService executorService = ... // Create ExecutorService.
Callable<Result> callable = new MyCallable(); // Create work to be done.
Future<Result> fut = executorService.submit(callable);
裹在Delayed
一個實現由此Delayed
的getDelay(TimeUnit)
方法返回所討論的工作的最大執行時間Future
。
public class DelayedImpl<T> implements Delayed {
private final long maxExecTimeMillis;
private final Future<T> future;
public DelayedImpl(long maxExecTimeMillis, Future<T> future) {
this.maxExecMillis = maxExecMillis;
this.future = future;
}
public TimeUnit getDelay(TimeUnit timeUnit) {
return timeUnit.convert(maxExecTimeMillis, TimeUnit.MILLISECONDS);
}
public Future<T> getFuture() {
return future;
}
}
DelayedImpl impl = new DelayedImpl(3000L, fut); // Max exec. time == 3000ms.
Add the `DelayedImpl` to a `DelayQueue`.
Queue<DelayedImpl> queue = new DelayQueue<DelayImpl>();
queue.add(impl);
從隊列中有一個線程反覆take()
和檢查每個DelayedImpl
的Future
是否是通過調用isDone()
完整的;如果不是,則取消該任務。
new Thread(new Runnable() {
public void run() {
while (!Thread.interrupted) {
DelayedImpl impl = queue.take(); // Perform blocking take.
if (!impl.getFuture().isDone()) {
impl.getFuture().cancel(true);
}
}
}
}).start();
主要優點這種方法是,你可以設置每個任務和延遲隊列不同的最長執行時間會自動的執行時間量最小剩餘返回任務。
4
亞當斯基:
我相信你的延遲接口的實現需要以正常工作的一些調整。如果從對象的實例化過去的時間量超過了最大生命週期,那麼'getDelay()'的返回值應該返回一個負值。爲了達到這個目的,你需要存儲創建任務的時間(可能開始)。然後每次'getDelay()'被調用時,計算是否超出了線程的最大生命週期。如:
class DelayedImpl<T> implements Delayed {
private Future<T> task;
private final long maxExecTimeMinutes = MAX_THREAD_LIFE_MINUTES;
private final long startInMillis = System.currentTimeMillis();
private DelayedImpl(Future<T> task) {
this.task = task;
}
public long getDelay(TimeUnit unit) {
return unit.convert((startInMillis + maxExecTimeMinutes*60*1000) - System.currentTimeMillis(), TimeUnit.MILLISECONDS);
}
public int compareTo(Delayed o) {
Long thisDelay = getDelay(TimeUnit.MILLISECONDS);
Long thatDelay = o.getDelay(TimeUnit.MILLISECONDS);
return thisDelay.compareTo(thatDelay);
}
public Future<T> getTask() {
return task;
}
}
相關問題
- 1. 最大執行時間錯誤處理
- 2. 處理Braintree超時的最佳方式
- 3. Java確定最佳線程數的最佳方式
- 4. 最佳多線程的方式來處理文件
- 5. 最大執行時間php.ini
- 6. PHP最大執行時間
- 7. 最大執行時間
- 8. Java:從多個線程檢索時間的最佳方法
- 9. 從Java執行AppleScript的最佳方法
- 10. 錯誤處理的最佳方式
- 11. 從C#處理.dbf的最佳方式
- 12. NullPointerException和處理它的最佳方式
- 13. Android中處理XML的最佳方式
- 14. 處理資源的最佳方式
- 15. 處理「重複」的最佳方式
- 16. 處理多個NSTableView的最佳方式
- 17. 處理JSON超時的最佳方法
- 18. 最大輸出的最佳線程數
- 19. 使用Java Servlets進行長時間登錄的最佳方式
- 20. 執行此操作的最佳方式
- 21. 執行搜索的最佳方式
- 22. Java - 處理大型GUI構造函數的最佳方法?
- 23. 多線程的最佳方式
- 24. 多線程的最佳方式?
- 25. Android:處理點,線和圓形手勢的最佳方式
- 26. 處理大型數據表的最佳方式是什麼?
- 27. 在codeigniter中處理大型js文件的最佳方式
- 28. 處理大型MySQL數據庫組織的最佳方式?
- 29. 作爲MySQL表主鍵處理大型(UUID)的最佳方式
- 30. 在Win Forms應用程序中處理多個線程的最佳方式
引發TimeoutException的Future.get(long timeout,TimeUnit unit)肯定會這樣做嗎?我認爲在這個例外情況下,你可以調用future.cancel(true)... – JeeBee 2009-10-08 12:30:13
Future.get(long,TimeUnit)將會阻塞一段指定的時間來完成特定的*未來。但是,我添加的解決方案允許您在單個線程中檢查*所有*可加密進程,而不是*阻止特定的進程。 假設我提交了一個需要5分鐘的Callable,在我的「檢查」線程中,我調用future.get(5L,TimeUnit.MINUTES)。然後提交另一個Callable,最大執行時間爲10秒。但是,線程不會查看第二個Callable是否已經運行了大於10秒,直到返回前一個阻塞調用。 – Adamski 2009-10-08 14:16:46