日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程语言 > java >内容正文

java

java 递归改非递归_使用Java ThreadLocals的意外递归保护

發(fā)布時(shí)間:2023/12/3 java 31 豆豆
生活随笔 收集整理的這篇文章主要介紹了 java 递归改非递归_使用Java ThreadLocals的意外递归保护 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

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è)選擇:

  • 花時(shí)間,坐下來,了解內(nèi)部原理,并正確地做。 到達(dá)自己的擴(kuò)展名后,您可能不應(yīng)該遞歸到訪問控制中。 在擴(kuò)展Jackrabbit的情況下,這可以通過使用系統(tǒng)會(huì)話在訪問控制算法中進(jìn)一步訪問節(jié)點(diǎn)來完成。 系統(tǒng)會(huì)話通常繞過訪問控制。
  • 要急躁,想要快速獲得結(jié)果,并通過技巧來防止遞歸
  • 當(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í)!

    參考:在Java,SQL和JOOQ博客上,我們的JCG合作伙伴 Lukas Eder 提供了Java ThreadLocals的意外遞歸保護(hù) 。

    翻譯自: https://www.javacodegeeks.com/2013/04/inadvertent-recursion-protection-with-java-threadlocals.html

    java 遞歸改非遞歸

    總結(jié)

    以上是生活随笔為你收集整理的java 递归改非递归_使用Java ThreadLocals的意外递归保护的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。