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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > java >内容正文

java

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

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

java 遞歸改非遞歸

對于那些使用第三方工具來嘗試擴展它們而又不完全了解它們的人來說,這是一個小技巧。 假定以下情況:

  • 您想擴展一個展示分層數據模型的庫(假設您要擴展Apache Jackrabbit )
  • 該庫在訪問內容存儲庫的任何節點之前會內部檢查訪問權限
  • 您想實現自己的訪問控制算法
  • 您的訪問控制算法將訪問內容存儲庫的其他節點
  • …進而會再次觸發訪問控制
  • …進而將再次訪問內容存儲庫的其他節點

…無限遞歸,如果不遞歸廣度優先,則可能導致StackOverflowError 。

現在,您有兩個選擇:

  • 花時間,坐下來,了解內部原理,并正確地做。 到達自己的擴展名后,您可能不應該遞歸到訪問控制中。 在擴展Jackrabbit的情況下,這可以通過使用系統會話在訪問控制算法中進一步訪問節點來完成。 系統會話通常繞過訪問控制。
  • 要急躁,想要快速獲得結果,并通過技巧來防止遞歸
  • 當然,您確實應該選擇選項1。但是,誰有時間了解所有內容?

    這是實現該技巧的方法。

    /*** 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;}}); }

    對main()方法的遞歸調用將被保護方法終止,并提早返回,而不是執行call() 。 也可以通過使用ThreadLocals Map進一步詳細說明此思想,允許指定各種鍵或上下文以防止遞歸。 然后,您還可以將Integer放入ThreadLocal ,在遞歸時將其遞增,最多允許N個遞歸級別。

    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;} }

    但是再說一次。 也許您只需要花幾分鐘時間,并了解主機庫的內部原理是如何工作的,并從一開始就將事情做好……與往常一樣,在應用技巧和黑客時!

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

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

    java 遞歸改非遞歸

    總結

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

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。