通常如下情況會取消:
1. 使用者發起取消請求
2. 現實的活動
3. 分解任務其中一條發現了解決方案,其他的就可以取消了
4. 分解任務其中一條發現了對於其他任務都有影響的錯誤,比如磁碟空間已滿,其他的可以取消了
5. 關閉, 當執行器關閉的時候,必須對正在處理及等待處理的任務進行優雅的關閉。
乙個最簡單的方式是,加上取消標記,cancel方法設定取消標記。 主流程中判斷取消標記,進行操作
public class testcallable
}class threadtest extends thread
system.out.println("被取消了");
}private void dosomething()
public void cancel()
}
這樣有個問題,如果dosomthing()的時候有阻塞,就永遠不會監測到cancel的狀態, 在jdk中我們還能使用專門為了取消而存在的中斷方法。
上面的**就會改為這樣:
public class testcallable
}class threadtest extends thread
} catch (interruptedexception e)
system.out.println("被取消了");
}private void dosomething() throws interruptedexception
public void cancel()
}
這裡再來看乙個用法,使用超時加上中斷來決定任務執行多久:
public static void main(string args)
}, 1, timeunit.seconds);
thread.start();
}
中斷策略
給執行緒加中斷有乙個原則就是一定要清楚中斷策略,否則就不要使用中斷方法。
使用future完成取消
例如:
public class testcallable catch (interruptedexception e) catch (executionexception e) catch (timeoutexception e)
}}class threadtest extends thread catch (interruptedexception e)
system.out.println("執行完成1");
}}
其中斷策略為:
.cancel(true),表示如果執行嘗試對當前執行緒進行中斷,一般是呼叫當前執行緒的.interrupt()方法
.cancel(false),表示如果沒執行則不會執行這個執行緒了,如果執行了,會等到執行完成。
比如生產者消費者模式。
因為其使用了take()阻塞的方法,能夠響應中斷,所以如果生產者阻塞了不是問題,但是這樣中斷可能不太好。
我們可以加入狀態標誌,當設定了關閉標誌之後,再生產就會丟擲異常, 這個跟executor的shutdown方法是一樣的。
還有一種方式是使用致命藥丸,就是在佇列中加入乙個特殊的任務,執行到這個藥丸就停止服務。
使用trackingexecutor類還能夠獲取已經取消了的任務, 用exec.getcancelledtasks()來獲取
任務中的異常處理
在executors.newfixedthreadpool(int , threadfactory threadfactory)中的第二個構造引數,是當乙個執行緒異常中斷的時候從這個factory中建立新的執行緒補充進去,可以用來做異常處理
或者一般情況下,使用future.get方法可以得到異常
正常關閉,system.exit()可以註冊關閉鉤子如下:
public class testcallable
});system.exit(0);
}}
後台執行緒
daemon的執行緒,不會影響執行緒的退出。不會執行finally塊,通常用於內部的事務處理。
避免使用finalizer.不提供任何保證,並且會帶來巨大的效能開銷。
併發程式設計實戰 8 任務的執行與取消
單執行緒順序執行任務,效率過低,沒有發揮多核的優勢。為每個任務分配乙個執行緒去執行,速度有所提公升,但是有很大的缺陷。生產環境中,每乙個任務分配乙個執行緒的方法存在一些缺陷,尤其是需要建立大量的執行緒時 提供一種標準的方法將任務的提交過程與執行過程解耦,並用runnable來表示任務。executo...
併發1 任務與執行緒
併發通常是提高執行在單處理器上的程式的效能。當以單執行緒執行所有任務時,雖然不會因為切換執行緒節省資源,但一旦出現阻塞 io請求等 則在阻塞接觸前單執行緒會發生等待。如果採用併發可在此時切換任務節省時間。所以沒有任務會被阻塞的情況下在單處理器上使用併發並沒有意義 cpu輪流給每個執行緒任務分配其占用...
併發程式設計實戰學習筆記(四) 任務執行
基於生產者 消費者模式,提交任務的操作相當於生產者 生成待完成的工作單元 執行任務的執行緒則相當於消費者 執行完成這些工作單元 儘管伺服器不會因為建立過多的執行緒而失敗,但在足夠長的時間內,如果任務到達的速度總是超過任務執行的速度,那麼伺服器仍有可能 只是更不易 耗盡記憶體,因為等待執行的runna...