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. 處理WCF超時的最佳方式
- 3. 處理Braintree超時的最佳方式
- 4. 最佳方式處理
- 5. 處理多線程清理的最佳方式
- 6. Java確定最佳線程數的最佳方式
- 7. 實現線程最大執行時間的最佳方式是什麼(在python/gtk中)?
- 8. 最佳多線程的方式來處理文件
- 9. PHP最大執行時間
- 10. 最大執行時間php.ini
- 11. 最大執行時間
- 12. Java:從多個線程檢索時間的最佳方法
- 13. 多線程執行時間最小化
- 14. 同時運行代碼處理多線程應用程序的最佳方法
- 15. 繪製線條的最佳方式java
- 16. NullPointerException和處理它的最佳方式
- 17. 從C#處理.dbf的最佳方式
- 18. 處理樹數組的最佳方式
- 19. 處理「重複」的最佳方式
- 20. 處理資源的最佳方式
- 21. 錯誤處理的最佳方式
- 22. Android中處理XML的最佳方式
- 23. 處理多個NSTableView的最佳方式
- 24. 從Java執行AppleScript的最佳方法
- 25. 管理線程的最佳方法?
- 26. 處理JSON超時的最佳方法
- 27. 最大輸出的最佳線程數
- 28. 執行搜索的最佳方式
- 29. 執行此操作的最佳方式
- 30. 使用Java Servlets進行長時間登錄的最佳方式
引發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