java 递归改非递归_使用Java ThreadLocals的意外递归保护
java 遞歸改非遞歸
對(duì)于那些使用第三方工具來嘗試擴(kuò)展它們而又不完全了解它們的人來說,這是一個(gè)小技巧。 假定以下情況:
- 您想擴(kuò)展一個(gè)展示分層數(shù)據(jù)模型的庫(假設(shè)您要擴(kuò)展Apache Jackrabbit )
- 該庫在訪問內(nèi)容存儲(chǔ)庫的任何節(jié)點(diǎn)之前會(huì)內(nèi)部檢查訪問權(quán)限
- 您想實(shí)現(xiàn)自己的訪問控制算法
- 您的訪問控制算法將訪問內(nèi)容存儲(chǔ)庫的其他節(jié)點(diǎn)
- …進(jìn)而會(huì)再次觸發(fā)訪問控制
- …進(jìn)而將再次訪問內(nèi)容存儲(chǔ)庫的其他節(jié)點(diǎn)
…無限遞歸,如果不遞歸廣度優(yōu)先,則可能導(dǎo)致StackOverflowError 。
現(xiàn)在,您有兩個(gè)選擇:
當(dāng)然,您確實(shí)應(yīng)該選擇選項(xiàng)1。但是,誰有時(shí)間了解所有內(nèi)容?
這是實(shí)現(xiàn)該技巧的方法。
/*** This thread local indicates whether you've* already started recursing with level 1*/ static final ThreadLocal<Boolean> RECURSION_CONTROL= new ThreadLocal<Boolean>();/*** This method executes a delegate in a "protected"* mode, preventing recursion. If a inadvertent* recursion occurred, return a default instead*/ public static <T> T protect(T resultOnRecursion,Protectable<T> delegate) throws Exception {// Not recursing yet, allow a single level of// recursion and execute the delegate onceif (RECURSION_CONTROL.get() == null) {try {RECURSION_CONTROL.set(true);return delegate.call();}finally {RECURSION_CONTROL.remove();}}// Abort recursion and return earlyelse {return resultOnRecursion;} }/*** An API to wrap your code with*/ public interface Protectable<T> {T call() throws Exception; }如下面的用法示例所示,這很容易工作:
public static void main(String[] args) throws Exception {protect(null, new Protectable<Void>() {@Overridepublic Void call() throws Exception {// Recurse infinitelySystem.out.println("Recursing?");main(null);System.out.println("No!");return null;}}); }對(duì)main()方法的遞歸調(diào)用將被保護(hù)方法終止,并提早返回,而不是執(zhí)行call() 。 也可以通過使用ThreadLocals Map進(jìn)一步詳細(xì)說明此思想,允許指定各種鍵或上下文以防止遞歸。 然后,您還可以將Integer放入ThreadLocal ,在遞歸時(shí)將其遞增,最多允許N個(gè)遞歸級(jí)別。
static final ThreadLocal<Integer> RECURSION_CONTROL= new ThreadLocal<Integer>();public static <T> T protect(T resultOnRecursion,Protectable<T> delegate) throws Exception {Integer level = RECURSION_CONTROL.get();level = (level == null) ? 0 : level;if (level < 5) {try {RECURSION_CONTROL.set(level + 1);return delegate.call();}finally {if (level > 0)RECURSION_CONTROL.set(level - 1);elseRECURSION_CONTROL.remove();}}else {return resultOnRecursion;} } 但是再說一次。 也許您只需要花幾分鐘時(shí)間,并了解主機(jī)庫的內(nèi)部原理是如何工作的,并從一開始就將事情做好……與往常一樣,在應(yīng)用技巧和黑客時(shí)!
翻譯自: https://www.javacodegeeks.com/2013/04/inadvertent-recursion-protection-with-java-threadlocals.html
java 遞歸改非遞歸
總結(jié)
以上是生活随笔為你收集整理的java 递归改非递归_使用Java ThreadLocals的意外递归保护的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 淘宝店铺备案怎么办理流程(淘宝店铺备案)
- 下一篇: 高度有用的Java ChronoUnit